<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Zeyuan Hu's Page</title><link href="https://zhu45.org/" rel="alternate"></link><link href="https://zhu45.org/feeds/all.atom.xml" rel="self"></link><id>https://zhu45.org/</id><updated>2026-01-03T23:01:02+08:00</updated><entry><title>Postmortem on TreeTracker Join: Simple, Optimal, Fast</title><link href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/" rel="alternate"></link><published>2026-01-03T23:01:02+08:00</published><updated>2026-01-03T23:01:02+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2026-01-03:/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/</id><summary type="html">&lt;p&gt;After five years of blood, sweat, and tears, &lt;a href="https://dl.acm.org/doi/10.1145/3774325"&gt;TreeTracker Join
(&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;)&lt;/a&gt; has finally
been published. The research itself is very interesting and kept me
hooked for five years. As a postmortem, I reflect on some of what I
learned during the process. I’m hoping this post can be …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After five years of blood, sweat, and tears, &lt;a href="https://dl.acm.org/doi/10.1145/3774325"&gt;TreeTracker Join
(&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;)&lt;/a&gt; has finally
been published. The research itself is very interesting and kept me
hooked for five years. As a postmortem, I reflect on some of what I
learned during the process. I’m hoping this post can be useful to my
fellow PhD students who are currently struggling to make progress or
finding their work a proper home.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#short-background-on-mathsfttj"&gt;Short background on \(\mathsf{TTJ}\)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lessons-learned"&gt;Lessons learned&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#algorithm-design-in-the-wild"&gt;Algorithm design in the wild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#when-talking-about-empirical-study-what-should-we-implement"&gt;When talking about empirical study, what should we implement?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#considerations-on-the-design-and-implementation-of-prototype"&gt;Considerations on the design and implementation of prototype&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#some-tips-on-java-and-software-engineering-in-general"&gt;Some tips on Java and software engineering in general&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#departing-thoughts"&gt;Departing thoughts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#acknowledgements"&gt;Acknowledgements&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id="short-background-on-mathsfttj"&gt;&lt;a name="background"&gt;&lt;/a&gt;Short background on &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;This research concerns query processing, specifically the evaluation
of queries that involve multiple joins, e.g., &lt;span class="math"&gt;\(R \Join S \Join T\)&lt;/span&gt; for
relations &lt;span class="math"&gt;\(R\)&lt;/span&gt;, &lt;span class="math"&gt;\(S\)&lt;/span&gt;, and &lt;span class="math"&gt;\(T\)&lt;/span&gt;. Those queries are known as &lt;em&gt;conjunctive
queries&lt;/em&gt;. It has been long known from database theory that evaluation
of an important subclass of conjunctive queries called &lt;em&gt;acyclic
conjunctive queries&lt;/em&gt; &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt; can be done very efficiently using an
algorithm called &lt;em&gt;Yannakakis’s algorithm&lt;/em&gt; (&lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt;) &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. (There
are many expositions on Yannakakis’s algorithm such as
&lt;a href="https://en.wikipedia.org/wiki/Yannakakis_algorithm"&gt;wikipedia&lt;/a&gt;, &lt;a href="https://remy.wang/blog/perfect-joins.html"&gt;blog
post&lt;/a&gt;,
&lt;a href="https://northeastern-datalab.github.io/topk-join-tutorial/slides/Anyk-Tutorial-Part2-OptimalJoins.pdf"&gt;slides&lt;/a&gt;,
and &lt;a href="https://youtu.be/0i8xC2dimoU?si=q8qrhPUuk8jnXXbz"&gt;video&lt;/a&gt;.)
However, the issue with this algorithm is that it is somewhat
&lt;a href="https://en.wikipedia.org/wiki/Galactic_algorithm"&gt;galactic&lt;/a&gt;
(theoretically optimal but empirically impractical) due to its poor
empirical performance and awkward algorithm structure. On the
empirical performance front, the core issue of &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; is that
it uses
&lt;a href="https://en.wikipedia.org/wiki/Join_(relational_algebra)#Semijoin"&gt;semijoin&lt;/a&gt;
to preprocess the input relations of a query so that the follow-up
joins only generate the tuples that can be part of the final query
result. There are two problems with semijoins:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Semijoin is really a heavy operation from empirical perspective: If
   one implements hash-based semijoin, building hash table and probing
   tuples against it can be quite expensive.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; just uses too many semijoins; if your query has &lt;span class="math"&gt;\(k\)&lt;/span&gt;
   relations for a positive integer &lt;span class="math"&gt;\(k\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; uses &lt;span class="math"&gt;\(2k-2\)&lt;/span&gt;
   semijoins. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The structural issue of &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; is mostly due to its algorithmic
ingredients that are not commonly-seen in popular database systems; it
utilizes a data structure called &lt;em&gt;join tree&lt;/em&gt; to guide how semijoins
and joins should be computed. Existing query systems work with &lt;em&gt;query
plans&lt;/em&gt;. It is not obvious on how to convert a query plan to a join
tree. (&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; takes a stab on this issue; see Lemma 4.6 of the
paper. For a more thorough treatment, check out this upcoming &lt;a href="https://arxiv.org/pdf/2509.14144"&gt;ICDT
‘26 paper&lt;/a&gt;.) Furthermore, adding
extra semijoins in a query plan for a query that doesn’t involve
&lt;code&gt;EXISTS&lt;/code&gt; can confuse the user and make query optimizer
&lt;a href="https://ieeexplore.ieee.org/document/914872"&gt;error-prone&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the past 3-4 years, many people have taken a stab at aforementioned
issues of &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; to make the algorithm practical and can be
accessible to wide database practitioners. (&lt;a href="https://arxiv.org/abs/2601.00098"&gt;This upcoming ICDT ‘26
paper&lt;/a&gt;
surveys this research thrust well.)  &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is one of those
stabs. The unique angle that &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; brings to the table is
that, instead of addressing the challenges following the algorithmic
framework laid out by &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; such as replacing semijoins with
Bloom filters or reducing the number of semijoins, &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is a
whole new algorithm that matches &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; runtime under data
complexity in the worst-case scenario. There are no semijoins at all
in &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. Instead of preprocessing input relations and
working with a join tree, &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; works with traditional query
plans and the evaluation starts right away. The big plus of
&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is that it is not much different (&lt;span class="math"&gt;\(\le 5\)&lt;/span&gt; lines of code
difference) from in-memory binary hash-join &lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt;. In fact,
&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; does no more number of hash table lookups than
&lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Two forms of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I should point out that during the many attempts at publishing the
work, two forms of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; appeared. One is the form that
eventually got published, which mostly uses &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, and
&lt;code&gt;for&lt;/code&gt; language constructs. The other one takes the &lt;a href="https://15445.courses.cs.cmu.edu/fall2021/notes/11-queryexecution1.pdf"&gt;iterator
form&lt;/a&gt;
consisting of &lt;code&gt;open()&lt;/code&gt;, &lt;code&gt;next()&lt;/code&gt;, and &lt;code&gt;close()&lt;/code&gt; methods. Under
iterator form, &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is an object in an object-oriented
language context and the algorithmic logic of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is
implemented in the three methods of the iterator form. The iterator
version of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is only available as the Algorithm 3.1
of the &lt;a href="https://arxiv.org/pdf/2403.01631v1"&gt;arXiv preprint
(version 1)&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h1 id="lessons-learned"&gt;Lessons learned&lt;/h1&gt;
&lt;p&gt;With the context of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; introduced, I
reflect on some lessons I learned during the process of getting paper
published. I list out all the past six submissions and corresponding
reviews that led to the final publication of the work, which I may
call back on during the reflection.&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Submission&lt;/th&gt;
&lt;th&gt;Reviews&lt;/th&gt;
&lt;th&gt;Supplementary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/pods2022.pdf"&gt;PODS 2022&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/pods2022-reviews.pdf"&gt;reviews&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/vldb2024.pdf"&gt;VLDB 2024&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/vldb2024-reviews.pdf"&gt;reviews&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/sigmod2024.pdf"&gt;SIGMOD 2025&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/sigmod2024-reviews.pdf"&gt;reviews&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/sigmod2024-extended.pdf"&gt;SIGMOD2025-extended&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/icdt2025.pdf"&gt;ICDT 2025&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/icdt2025-reviews.pdf"&gt;reviews&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/cidr2025.pdf"&gt;CIDR 2025&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/cidr2025-reviews.pdf"&gt;reviews&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/TODS.pdf"&gt;TODS 2025&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/TODS-review1-pub.pdf"&gt;reviews&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://zhu45.org/posts/2026/Jan/03/postmortem-on-treetracker-join-simple-optimal-fast/TODS-revision.pdf"&gt;revision&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="algorithm-design-in-the-wild"&gt;&lt;a name="algorithm"&gt;&lt;/a&gt;Algorithm design in the wild&lt;/h2&gt;
&lt;p&gt;This is the first time I designed an algorithm out of classroom
setting. The task was to adapt &lt;a href="https://www.sciencedirect.com/science/article/abs/pii/0004370294900647"&gt;TreeTracker
algorithms&lt;/a&gt;
from constraint satisfaction problem (CSP) into relational database
setting and the result of the adaptation has to take the iterator form
(Algorithm 3.1 of the
&lt;a href="https://arxiv.org/pdf/2403.01631v1"&gt;preprint&lt;/a&gt;). The difficulty of the
task was fair and well-suited for my skillset. There are two
algorithms in the paper &lt;span class="math"&gt;\(\mathsf{TT}1\)&lt;/span&gt; and
&lt;span class="math"&gt;\(\mathsf{TT}2\)&lt;/span&gt;. &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is an adaptation of &lt;span class="math"&gt;\(\mathsf{TT}1\)&lt;/span&gt; &lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;There are a few things I tried and I found them helpful in designing
the algorithm.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Explain the original algorithm in your own words.&lt;/strong&gt;  The first
   thing I did after reading the original TreeTracker paper was to
   rewrite the proof of correctness and runtime analysis in my own
   words. I found there are three benefits of doing this. First,
   rewriting helps to fill the omitted details in the original
   proof. Those details might take short amount of seconds to
   reconstruct in mind but they can add a lot of delay for me to start
   to make progress in understanding the proof if I have to do it
   every time especially in the first few times where I haven’t gained
   much intuition about the ideas behind the proof. Second, rewriting
   helps to gain some intuition. Since I rewrote the proof in my own
   words, I had to ensure the correctness of proof remains
   intact. Thus for every sentence I wrote I always asked myself if
   there are any considerations that the authors write like this; can
   I say the sentence differently? If so, does the sentence break the
   whole proof? By answering those questions, I felt I gained more
   intuition on the ideas behind the proof and the intuition on the
   algorithm and its properties. Third, rewriting allows me to
   forget. Since I had already rewritten the proof with great care in
   my note, I had the freedom to forget those details. I usually just
   had some high-level idea of how the proof goes in my mind. Since
   proof is an application of some properties of the proposed
   algorithm, the high-level idea of proof is in a way captures the
   essence of the algorithm. If I had to remember every detail of the
   proof, I felt there wasn’t brain power for understanding new things
   or thinking about the problem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;“The art of doing mathematics is finding that special case that
   contains all the germs of generality.”&lt;/strong&gt; This is a quote from David
   Hilbert. I gained a fairly deep appreciation on this quote during
   the design of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. My takeaway on the quote is that we
   need to find an example that is simple enough that captures all the
   necessary ingredients of the algorithm. Thus by having an algorithm
   that handles this example, we obtain an algorithm that
   automatically handles all possible inputs. In a way, the example
   itself encodes the algorithm. In the case of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, my
   personal favorite simple but general example is Example 1 from &lt;a href="https://arxiv.org/pdf/2403.01631v1"&gt;the
   arXiv preprint&lt;/a&gt;. The generality
   is captured by the branching at relation &lt;span class="math"&gt;\(S\)&lt;/span&gt;: instead of every
   relation in the join tree has at most one child, some relation
   needs to have at least two children in order to capture backjumping
   aspect of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. If one only uses chain query, where each
   internal node in the join tree has exactly one child, the resulting
   &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is not generalized enough to handle all the possible
   inputs. Certainly, there are multiple issues with this example such
   as it actually shows &lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt; can also be optimal, and it
   includes deletion propagation and no-good list (See Appendix R of
   &lt;a href="https://arxiv.org/pdf/2403.01631v3"&gt;v3 version of the preprint&lt;/a&gt;),
   which are not necessary key ingredients of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; for the
   proposed runtime guarantee. Nevertheless, the example is sufficient
   enough to have the correct algorithm designed; the rest is
   optimization of the example.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Documentation to have a sense of progress.&lt;/strong&gt; Ryan O’Donnell has
   this quote “Philosophy about how to do research: Make 1% progress
   per day, for 100 days. Then you will solve your problem.” My
   takeaway from this is that it’s very unlikely to design an
   algorithm in one day. Design of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; roughly took me one
   year. It would feel discouraged if I cannot visibly see my
   progress; after all, a failed attempt is progress because the
   failed attempt rules out a possibility and equips me with more
   understanding of the problem. If I can rule out 100 different
   possibilities, there is a decent chance that I can find the answer
   to my question. With this mindset, I started to record my attempts
   from day one in a LaTeX document and I could see my progress by
   just adding new content to this document. I finally obtained
   &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; after this document had grown to around 1 MiB and I felt
   quite satisfied each day after
   adding a page or so to this document.   &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Writing programs in algorithm design (a.k.a. system-assisted
   algorithm design).&lt;/strong&gt; I wrote two major programs during the design
   of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. First, I implemented &lt;span class="math"&gt;\(\mathsf{TT}2\)&lt;/span&gt; of the
   paper. The role this program served was manifold. First, it helped
   me to better understand the algorithm. Both the &lt;span class="math"&gt;\(\mathsf{TT}2\)&lt;/span&gt;
   description and the associated proofs use a lot of prose, which is
   inherently inaccurate &lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;4&lt;/a&gt;&lt;/sup&gt;. To ensure I had the correct
   understanding of the algorithm, gained a sense of concreteness, and
   could continue to build up the correct intuition, I found that
   implementing the algorithm and letting it run on a few examples
   helped. Second, it made me appreciate the complexity of the
   algorithm, which pushed me to aim for a simpler algorithm, which
   led to TT1 and eventually &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. The second major program
   I wrote was a query instance generator where it produced a query in
   the form of a join tree and associated relation instances, which
   could be randomly generated or manually specified. The major
   benefit of the program was that it generated a lot of examples for
   me to look at. Those examples were important because they quickly
   got me jumpstarted on the design without making the task look too
   daunting. Additionally, I think of an algorithm as a procedure to
   handle a class of inputs that satisfy certain restriction (e.g.,
   acyclic conjunctive queries) and the goal of the algorithm is to
   produce the desired output (e.g., the correct query result). Thus
   the design loop of an algorithm consists of writing the initial
   procedure, finding where the procedure breaks on certain inputs,
   patching the procedure to handle the broken inputs, and repeating
   until the procedure can handle all possible inputs. Examples helped
   in all aspects of this design loop: they helped me to write the
   initial algorithm, then some examples broke my algorithm, and after
   a patch, those examples allowed me to verify that the patch could
   indeed work. As one can see, the loop can be easily automated and
   that is what I did: the generator itself ran my algorithm and
   compared the output with the results of evaluating the same query
   in a third-party database like PostgreSQL. I immediately received
   feedback on whether the algorithm broke. Immediate feedback is
   crucial because it can be very messy to trace through the
   evaluation of a query using a plan consisting of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;
   iterators to check if &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; worked correctly. I found it
   was better to perform tracing when the algorithm broke. With the
   loop largely automated, I could spend my energy focusing on
   thinking about good examples that could capture all the ingredients
   of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; and designing the algorithm itself.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Limitation of system-assisted algorithm design&lt;/p&gt;
&lt;p&gt;I found system-assisted algorithm design particularly suited for &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;
because the problem input space is discrete and structured around join
trees. Furthermore, checking the correctness of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; in
its iterator form–where the algorithm essentially takes the form of
mutual recursion–is a tedious task for a human to trace but
trivial for a machine.&lt;/p&gt;
&lt;p&gt;However, for continuous problems (like &lt;a href="https://arxiv.org/pdf/2507.04485"&gt;facility placement on a real
line&lt;/a&gt;) where the problem input
space can be vast, it’s not very straightforward to
apply this idea immediately. In such cases, classical methods of conjecture and refinement remain more
effective. Once I have a classification of
the problem inputs and derive the properties that the desired
algorithm should possess, the algorithm becomes self-evident,
making system-assisted design unnecessary.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="when-talking-about-empirical-study-what-should-we-implement"&gt;When talking about empirical study, what should we implement?&lt;/h2&gt;
&lt;p&gt;For work like &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; that simplifies an existing algorithm
without breaking any complexity barrier (&lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; is already an
optimal algorithm; so what to break anyway), PODS 2022 reviews taught
me that the best bet to get the work published within database
community is to implement something and send it to a system conference
like &lt;a href="https://sigmod.org/"&gt;SIGMOD&lt;/a&gt;,
&lt;a href="https://www.vldb.org/conference.html"&gt;VLDB&lt;/a&gt;, or some journal like
&lt;a href="https://dl.acm.org/journal/tods"&gt;TODS&lt;/a&gt;. (In broad algorithm or
theoretical computer science community, there exist conferences like
&lt;a href="https://www.siam.org/conferences-events/siam-conferences/sosa26/"&gt;SOSA&lt;/a&gt;
that might solicit work like &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. However, it’s not until
&lt;a href="https://arxiv.org/pdf/2507.04485"&gt;very recently&lt;/a&gt; I learned about how
to write a theory paper properly; our PODS 2022 submission is unlikely
to make the cut as a theory paper to SOSA.) A fairly natural question
to ask next is if we implement something, what should we implement?
From my experience, there are two types of implementations we can
consider:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Algorithm comparison&lt;/strong&gt; where one implements the proposed
   algorithm and compare with existing algorithms to highlight and
   confirm the proposed algorithm behavior indeed aligns with the
   design and analysis. Furthermore, such comparison highlights
   different algorithm behaviors against different kinds of inputs
   that are usually not well-covered in traditional worst-case
   scenario Big-Oh analysis. Examples include sections 5.3 and 5.4 of
   our SIGMOD 2025 submission and section 6 of
   &lt;a href="https://epubs.siam.org/doi/epdf/10.1137/1.9781611978759.10"&gt;Zip-Tries&lt;/a&gt;. (This
   type of implementation can even motivate the design and analysis of
   algorithms; see testimony in section 4 of &lt;a href="https://arxiv.org/pdf/2010.02116"&gt;this
   paper&lt;/a&gt; and section 1 of &lt;a href="https://arxiv.org/pdf/1210.0481"&gt;this
   paper&lt;/a&gt;.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;System comparison&lt;/strong&gt; where one integrates the proposed algorithm
   into a large system (or builds a new system from scratch with the
   proposed algorithm) and compares the new system with an existing
   system that serves the same purpose (e.g., query systems) to show
   end-to-end performance advantages of the new system. Many papers
   published in system conferences like SIGMOD, VLDB, or
   &lt;a href="https://sigops.org/s/conferences/sosp/2026/"&gt;SOSP&lt;/a&gt; have this type
   of implementation. It’s clear that the system comparison applies to
   a broader scope than the algorithm comparison: system comparison
   not only applies to the study of algorithms but also to exploration
   of new system design ideas and principles. (&lt;a href="https://web.archive.org/web/20250310064400/https://blog.xiangpeng.systems/posts/system-researchers/"&gt;This blog
   post&lt;/a&gt;
   gives a more detailed recount of the system comparison and the
   perspectives it entailed.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I used to believe that it was sufficient to implement algorithmic
comparison for &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;. However, reviews I received (search
using keywords “system” or “DuckDB” in VLDB 2024, SIGMOD 2025, CIDR
2025, and TODS 2025 reviews) put heavy premiums on the system
comparison. The biggest confusion I had on applying system comparison
to algorithmic work like &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; is that system comparison
introduces lots of moving parts that may not be relevant to the
algorithm itself and the end-to-end performance advantage of the new
system with the proposed algorithm may not indicate the performance
improvement is due to algorithm improvement. For example, suppose I
have an algorithm and I integrate it into two query systems &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; and
&lt;span class="math"&gt;\(S_2\)&lt;/span&gt;. The only difference between &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(S_2\)&lt;/span&gt; is that compared to
&lt;span class="math"&gt;\(S_2\)&lt;/span&gt;, &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; assumes single user scenario and doesn’t implement
session manager and worry about transactions. If empirically I show
&lt;span class="math"&gt;\(S_1\)&lt;/span&gt; is faster than &lt;span class="math"&gt;\(S_2\)&lt;/span&gt;, can I claim that &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; being faster is
because it has a better algorithm? More generally speaking, if the
system &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; consists of &lt;span class="math"&gt;\(X\)&lt;/span&gt; components with one component being the
proposed algorithm &lt;span class="math"&gt;\(A\)&lt;/span&gt; and system &lt;span class="math"&gt;\(S_2\)&lt;/span&gt; consists of &lt;span class="math"&gt;\(Y\)&lt;/span&gt; components
with one component being the compared algorithm &lt;span class="math"&gt;\(B\)&lt;/span&gt;, in order to pin
down &lt;span class="math"&gt;\(A\)&lt;/span&gt; is indeed empirically better than &lt;span class="math"&gt;\(B\)&lt;/span&gt;, I need to rule out the
possibilities that the performance advantage is not coming from the
rest of &lt;span class="math"&gt;\(X-1\)&lt;/span&gt; components of &lt;span class="math"&gt;\(S_1\)&lt;/span&gt;, which requires substantial
effort. The end result of doing so effectively reduces system
comparison to algorithm comparison. Then the question is why do we not
doing system comparison from the beginning? With this mindset, I
implemented a &lt;a href="https://github.com/xxks-kkk/treetracker"&gt;query system&lt;/a&gt;
from scratch that supports &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt;,
&lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt;, and other relevant algorithms. Every algorithm being
compared such as &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; enjoys the same setup as &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;
and the only difference in terms of code being executed is the
algorithm itself. One of the reasons that &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; got published
is because &lt;a href="https://remy.wang/"&gt;Remy&lt;/a&gt; came in and directed the effort
of implementing a variation of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; in Rust that beats
DuckDB to fullfil the requirement of system comparison. (&lt;a href="https://remy.wang/blog/duckdb.html"&gt;This blog
post&lt;/a&gt; articulates the potential
impact of forcing people to compare against DuckDB on database
research and a related &lt;a href="https://arxiv.org/pdf/2504.08948"&gt;panel discussion in VLDB
2025&lt;/a&gt; on the phenomenon of
“reviewing process may over-index on work that must be faster than
some baseline”.)&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;The “approximation from below” perspective&lt;/p&gt;
&lt;p&gt;The way now I reconcile and justify the need of system comparison
on algorithmic work is to view system comparison as an approximation
of the proposed algorithm performance from below.&lt;/p&gt;
&lt;p&gt;The reasoning is as follows. Suppose I have a new algorithm
&lt;span class="math"&gt;\(A\)&lt;/span&gt; and a target algorithm &lt;span class="math"&gt;\(B\)&lt;/span&gt; that I would like to compare with.
I implement &lt;span class="math"&gt;\(A\)&lt;/span&gt; in a system &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; that has &lt;span class="math"&gt;\(X\)&lt;/span&gt;
extra components. Algorithm &lt;span class="math"&gt;\(B\)&lt;/span&gt; is built inside a system &lt;span class="math"&gt;\(S_2\)&lt;/span&gt; that 
has &lt;span class="math"&gt;\(Y\)&lt;/span&gt; more components. Suppose &lt;span class="math"&gt;\(X &amp;lt; Y\)&lt;/span&gt; and assume all &lt;span class="math"&gt;\(X\)&lt;/span&gt;
components and &lt;span class="math"&gt;\(Y\)&lt;/span&gt; components have the same performance.
System &lt;span class="math"&gt;\(S_2\)&lt;/span&gt; serves as a lower bound on the performance of &lt;span class="math"&gt;\(A\)&lt;/span&gt;
because even though it may not be conclusive that &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; runs
faster than &lt;span class="math"&gt;\(S_2\)&lt;/span&gt; indicating &lt;span class="math"&gt;\(A\)&lt;/span&gt; being better than &lt;span class="math"&gt;\(B\)&lt;/span&gt;, 
&lt;span class="math"&gt;\(S_1\)&lt;/span&gt; slower than &lt;span class="math"&gt;\(S_2\)&lt;/span&gt; definitely indicates that &lt;span class="math"&gt;\(A\)&lt;/span&gt; does not
offer performance advantages. In other words, there is a possibility
that algorithm &lt;span class="math"&gt;\(B\)&lt;/span&gt; in the algorithm comparison may not
be implemented properly, which results in the baseline being too
low and algorithm &lt;span class="math"&gt;\(A\)&lt;/span&gt; does not yet offer a real-world advantage;
system comparison rules out such possibility. &lt;/p&gt;
&lt;p&gt;Certainly, it is a big “if” that all &lt;span class="math"&gt;\(X\)&lt;/span&gt; components and &lt;span class="math"&gt;\(Y\)&lt;/span&gt;
components have the same performance. (Or generally speaking, the
total runtime of all the not-&lt;span class="math"&gt;\(A\)&lt;/span&gt; components of system &lt;span class="math"&gt;\(S_1\)&lt;/span&gt; is
less than or equal to the total runtime of all the not-&lt;span class="math"&gt;\(B\)&lt;/span&gt;
components of system &lt;span class="math"&gt;\(S_2\)&lt;/span&gt;.) Ensuring that holds requires
significant engineering effort and it is not directly relevant to
the innovation of algorithm &lt;span class="math"&gt;\(A\)&lt;/span&gt;. A good heuristic to satisfy the “big
if” is to make &lt;span class="math"&gt;\(X\)&lt;/span&gt; as small as possible through a simple,
high-quality prototype design that avoids unnecessary components.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once I adopted this “approximation” view on system comparison, I could see
algorithm comparison can also be done approximately. In an ideal
world, all algorithms are done in an apple-to-apple comparison fashion
such that the only “delta” in terms of performance difference among
algorithms is the algorithms themselves. In SIGMOD 2025 submission, I
was instructed to do so. Since both &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt;
use join tree, and &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt; use query plans,
the most fair way was to build an optimizer that generate query plans
and join trees such that all algorithms use the same query plans and
the same join tree if needed. However, the issue with this empirical
setup was that it made the water muddy meaning we need to introduce
how optimization of join trees and generation of query plans for
acyclic conjunctive queries are done, which can be treated in a
separate paper. To not let the issue of query optimization distracts
the reader, many papers (such as &lt;a href="https://www.vldb.org/pvldb/vol10/p889-zhu.pdf"&gt;Lookahead Information
Passing&lt;/a&gt;, the published
version of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, and &lt;a href="https://arxiv.org/abs/2307.15255"&gt;Predicate
Transfer&lt;/a&gt;) consider the proposed
algorithm purely as a runtime technique, where the algorithm takes in a
query plan that is generated from a baseline system (in the case of
&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, plans are taken from SQLite and PostgreSQL) and then
measure the empirical performance. This way we approximate the best
possible performance of both the proposed algorithm and the baseline
algorithm with the assumption that additional query optimization can
unlock even better performance of respective algorithm. Then the
comparison is done based on the proxies of both algorithms.&lt;/p&gt;
&lt;p&gt;Sometimes the algorithm comparison can be mixed with system comparison
because system being compared is a lower bound to the target
algorithm. In TODS submission, we used PostgreSQL as the lower bound to
all the implemented algorithms in the query engine namely
&lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt;, and &lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt;. We ensured
&lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt; ran faster than PostgreSQL. Since &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; and
&lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt; ran faster than &lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt; in most cases, we
eliminated the possibility of a “straw man” implementation of baseline
algorithms. An extra consideration on choosing PostgreSQL is that its
architecture was mostly aligned with ours, most notably, row-oriented
iterator-based execution model. The challenge here was that the
community really likes DuckDB and many bad decisions described
&lt;a href="#design"&gt;later&lt;/a&gt; on the design of the engine don’t allow the engine to
easily beat DuckDB. Eventually, we presented both algorithm comparison
and system comparison separately with two different prototypes.&lt;/p&gt;
&lt;!-- As a corollary, algorithm comparison can be viewed as showing --&gt;
&lt;!-- performance advantage from the positive side by showing the "upper --&gt;
&lt;!-- bound", i.e., how good the proposed algorithm $A$ can be. --&gt;
&lt;p&gt;One might have this fear that system comparison involves a ton of
work; I certainly did because I had been avoiding system comparison
all along (The first review suggests system comparison is from VLDB
2024, which I received in 2023). In the deep down, I didn’t have this
approximation perspective and I thought it would be a ton of work to
do fully rigorous way given all the variables we need to control
across multiple systems being compared. However, if all we did was to
compare proxies of both algorithms, there is, in fact, a lot of
leeway. I think the challenge here is to not know what are sufficient
ingredients we need to build to carry out the system comparison; a
more experienced person can really help a lot on this. For example, I
didn’t need to build a whole optimizer at all for both algorithm and
system comparisons.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;“If a thing is worth doing, it’s worth doing badly”&lt;/p&gt;
&lt;p&gt;During the empirical study of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, I was haunted by the
idea that a valid system comparison required building a perfect,
end-to-end system from scratch to beat DuckDB–a task I estimated would
take at least a year. However, I later learned that I didn’t need a
perfect system; a barebone “semi-system” was sufficient to demonstrate
the algorithm’s potential and fulfill the referees’ requirements.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="considerations-on-the-design-and-implementation-of-prototype"&gt;&lt;a name="design"&gt;&lt;/a&gt;Considerations on the design and implementation of prototype&lt;/h2&gt;
&lt;p&gt;With the algorithm in hand and an understanding of the types of
implementations needed for the empirical study, one must decide how to
design a prototype that effectively supports the evaluation. The
decision naturally couples with experimental design. There remain,
however, several considerations regarding the design of the
prototype–areas where I made both good and bad calls in hindsight.&lt;/p&gt;
&lt;p&gt;The common wisdom in building a research prototype is to treat the
prototype as “one-shot” meaning it is a software that will not get
maintained and the main purpose that such prototype serves is to
generate numbers for plots used in the paper &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;5&lt;/a&gt;&lt;/sup&gt;. The biggest merit
of this wisdom I think is the emphasis of being “agile” that prevents
over-engineering and takes necessary shortcuts to deliver
results. However, I think we should be careful about when and what
shortcuts we take.&lt;/p&gt;
&lt;p&gt;The biggest good call I made was to take a shortcut on prototype
design but not the actual implementation. That is, I aimed for the
simplest possible design but when it came down to the actual
implementation of the design, I strove for production-ready
engineering quality. Since I was going to build the query engine all
by myself in a limited time, it’s unrealistic to build a fully-fledged
query engine; trade-offs had to be made. As a result, I aimed for the
most barebone query engine possible. The guiding principle was that if
there was no code, there was no bug, and there was no performance
penalty. Thus the whole query engine was modeled after
&lt;a href="https://trino.io/"&gt;Trino&lt;/a&gt;, which I was fairly familiar with: the
engine used JDBC to connect to some relational database (SQLite,
PostgreSQL, and DuckDB are supported) and the data were pulled into
the engine to perform join computation. Since SQLs are merely some
specification of certain computations, I could implement the
specification imperatively using a set of low-level APIs to specify
the computation. As a result, no parser was built. The main code path
was fairly simple: taking a specification of a join query and pull the
data from the connected database and produce the query result. Such
simple design enabled quick adaption of the prototype for unplanned
empirical evaluation needs. For example, since SIGMOD 2025 pursues an
apple-to-apple comparison setup, an optimizer, that was not planned in
the design of the prototype, had to be in-place. Since the design of
the query engine was so simple, I could model the optimization of
different algorithms (&lt;span class="math"&gt;\(\mathsf{YA}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathsf{HJ}\)&lt;/span&gt;,
and Predicate Transfer) as plugins to the engine, which could be
enabled or disabled based on the needs. Query optimization as a plugin
saved me a lot of headache later on in TODS submission because we
switched back to runtime technique comparison philosophy and
completely remove the query optimization work of algorithms. In fact,
experiments done in SIGMOD 2025 submission but removed in the TODS
submission were all implemented as plugins, which gave me plenty of
flexibilities to cater various instructions. When it came to the
implementation, I extensively used &lt;a href="https://guava.dev/releases/19.0/api/docs/com/google/common/base/Preconditions.html"&gt;checkState() or
checkArgument()&lt;/a&gt;
to explicitly solidify the assumption that I made on the
implementation of the methods. Also, nontrivial methods were
thoroughly tested. For example, all the algorithms implemented were
covered by &lt;a href="https://github.com/xxks-kkk/treetracker/blob/0a22c83d838f3d4ecd0f66bb6f89b1f00da2dd0a/treeTracker/treetracker-relational/src/main/java/org/zhu45/treetracker/relational/operator/testCases/InstantiateTestCases.java#L35"&gt;the same suite of queries and relation
instances&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, there were many bad calls I made that I wish I could done
differently. The biggest one was to extend the database and query
generator that facilitated the design of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; into a query
engine for empirical study. This decision had two significant
drawbacks that I realized later:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The generator was written in Java for fast development. (The
   flexibility offered by Python is too much for me; I wanted to use a
   moderately restrictive language with native support for type
   checking and rich ecosystem. Java is a nice language for this
   purpose and I am quite familiar with.) However, when it came to
   performance optimization in the late stage, Java program was not
   easy to optimize straightforwardly. For example, all the data were
   stored in a underlying database like DuckDB and fetched on-demand
   using JDBC. To compare with in-memory database system, I needed to
   make my setup as close to in-memory as possible. In Java, I needed
   to deal with on-heap memory managed by JVM and off-heap memory if I
   wanted to completely buffer the database instance inside the
   memory. This was more cumbersome to deal with compared to other
   language like Rust.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The generator used a federation database architecture where tuples
   were fetched from an external database via JDBC. The benefit of
   this design was that it allowed me to avoid managing storage part
   myself and to ingest new relations easily for algorithm
   development. Furthermore, in the case of conjunctive queries like
   the ones in
   &lt;a href="https://github.com/gregrahn/join-order-benchmark/blob/master/10a.sql"&gt;JOB&lt;/a&gt;,
   all the selection predicates are pushed down to and evaulated by
   the underlying database. Thus I could solely focus on the join
   evaluation part of the queries. However, the design was a bad call
   for a performance-focused prototype. By treating the data source as
   a separate entity, I introduced a massive communication bottleneck
   between the storage and query processing. As described in this
   &lt;a href="https://www.starburst.io/blog/jdbc-trino-starburst/"&gt;post&lt;/a&gt;, JDBC
   is not designed to transfer a large volume of data; it introduces
   significant serialization and deserialization overhead. Every tuple
   fetched requires the underlying database to serialize internal
   binary records into a wire protocol, which the JDBC driver must
   then deserialize into Java objects. This ‘marshaling’ process
   consumes significant CPU cycles and creates memory pressure, often
   making the communication interface—rather than the join
   algorithm—the primary bottleneck. To mitigate the issue, I tweaked
   &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/sql/Statement.html#setFetchSize-int-"&gt;setFetchSize&lt;/a&gt;,
   which decides how many tuples are fetched in a batch from data
   source. However, there was a trade-off: If the value set too large,
   then effectively one maintains two copies of the data, which run
   into the risk of out-of-memory for JVM. For example, if the query
   engine fetched a table of 10000 rows, the 10000 rows were cached in
   JDBC connection. Since the engine had to map each row fetched by
   JDBC to an internal row representation, in the worst-case scenario,
   20000 rows are maintained inside JVM heap, which caused significant
   memory pressure. On the other hand, if one sets the value of
   &lt;code&gt;setFetchSize&lt;/code&gt; too small, &lt;code&gt;next()&lt;/code&gt; call on
   &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html"&gt;resultSet&lt;/a&gt;
   can take long time. Furthermore, the JDBC driver implementation can
   impact the engine performance a lot. I initially used PostgreSQL to
   store the data. PostgreSQL JDBC driver is implemented purely &lt;a href="https://github.com/pgjdbc/pgjdbc"&gt;in
   Java&lt;/a&gt;, which is slower than
   DuckDB JDBC driver, which is implemented &lt;a href="https://github.com/duckdb/duckdb-java/tree/main"&gt;in
   C++&lt;/a&gt;. The takeaway
   from working with JDBC is that it is pretty neat for fast
   prototyping. However, when we build a research prototype for system
   comparison, it’s probably better to use something else. One idea
   used in the eventual TODS paper was to implement a prototype as a
   barebone program where all the data were stored as Parquet
   files. Then we used &lt;a href="https://pola.rs/"&gt;Polars&lt;/a&gt; to read those
   Parquet files into memory and stored as
   &lt;a href="https://doc.rust-lang.org/book/ch05-01-defining-structs.html"&gt;structs&lt;/a&gt;. This
   design was very intuitive and completely removed the hassle of
   dealing with JDBC in performance optimization.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In hindsight, I disregarded a famous quote from Fred Brooks “In most
projects, the first system built is barely usable … Hence plan to
throw one away; you will, anyhow.”&lt;/p&gt;
&lt;p&gt;Another important point is to study benchmark workload. The prototype
was expected to run on a fixed workload and such workload was known
beforehand, which contained rich opportunities to enable simplification
of prototype design and implementation. For example, if any pair of
relations joins on an integer column only, it is not wise to implement
more generic case where two tables can join on a composite key or on a
string column.&lt;/p&gt;
&lt;h2 id="some-tips-on-java-and-software-engineering-in-general"&gt;Some tips on Java and software engineering in general&lt;/h2&gt;
&lt;p&gt;The development of the prototype effectively started from day one
given the &lt;a href="#design"&gt;decision&lt;/a&gt; of extending the query generator for the
&lt;a href="#algorithm"&gt;purpose of algorithm design&lt;/a&gt; into a research
prototype. However, the generator itself was not built with the
performance-centric in mind. Therefore a huge chunk of time was spent
optimzing the implementation so that the engine can outperforms
various system baselines. The following tips are ones I found useful
during the optimization process.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Profiling.&lt;/strong&gt; I think the biggest tip is to use some profiler to see
   where the code spent time. There is a famous 90/10 rule on system
   performance optimization, which says something like one should
   spend 90% of the effort on 10% of the code of the system because
   that 10% of the code makes the biggest impact on the system
   performance. (I believe I read it somewhere on the web but I cannot
   find the version I read; the closest one I found is from &lt;a href="https://www.cs.cmu.edu/~pattis/quotations.html"&gt;Richard
   Pattis&lt;/a&gt;.) In
   order to identify this 10% mission-critical code, it’s inevitable
   to use profiler. Once we start to profile the code, the rest
   becomes easy: we just enter the loop of squashing the most
   significant performance anomaly shown by the profiler and repeat
   until there is absolutely nothing to be optimized. Another purpose
   of using profiler is to generate plots like runtime breakdown
   (e.g., Figure 7-9 in the &lt;a href="https://arxiv.org/pdf/2403.01631v1"&gt;preprint
   (v1)&lt;/a&gt;) in empirical section of
   the paper. Using print statement like &lt;code&gt;System.out.println&lt;/code&gt; won’t
   be precise enough as the operation of printing to screen adds
   significant runtime overhead, which makes the breakdown of your
   algorithm runtime inaccurate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Replace Java Streams with Vanilla Loops.&lt;/strong&gt; I used &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html"&gt;Stream
   API&lt;/a&gt;
   extensively in the code because of its clean look. However,
   profiling showed that the Stream API added unnecessary abstraction
   layers. Rewriting these as vanilla loops allowed the Just-in-Time
   compiler to optimize the code more effectively and reduced the
   allocation of short-lived objects.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use primitive type if possible.&lt;/strong&gt; For example, instead of
   &lt;code&gt;Integer&lt;/code&gt;, we use &lt;code&gt;int&lt;/code&gt;. As a concrete example, all queries in
   &lt;a href="https://github.com/gregrahn/join-order-benchmark/tree/master"&gt;JOB&lt;/a&gt;
   join any two relations on a single integer column. When we read
   tuples from underlying database, we need to map those tuples into
   our internal row representation. Naively, we can wrap each integer
   value into &lt;code&gt;Integer&lt;/code&gt;. However, such wrapping adds significant
   penalty: First, we need to do wrapping for each tuple and each
   integer column (4000 wrapping operations for 1000 tuples from a
   table of four integer columns). Second, such wrapping achieves
   nothing because later on, when we do join, we need to extract the
   join attribute value from the row and use it to obtain the hash
   bucket from the hash table. During the process, the only
   information we need is the integer value that &lt;code&gt;Integer&lt;/code&gt; object
   contains and the wrapping doesn’t add anything for this purpose.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Map out unnecessary columns.&lt;/strong&gt; As mentioned in the &lt;a href="#design"&gt;prior
   section&lt;/a&gt;, JDBC can impose a significant performance
   penalty. This tip is specific to query engine that maps out
   unnecessary columns that are not used in a given query. Doing so
   reduces the amount of tuples need to be fetched from the underlying
   database. This performance optimization tip falls into a broad
   category of using some query analysis to reduce the work actually
   done during the query runtime.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Preallocate fixed-length arrays.&lt;/strong&gt; It’s better to preallocate a
   fixed length of an array that has sufficient size during the whole
   life cycle of query evaluation. If we go with the default array
   length, we run into the situation of constantly resizing the array,
   which makes the performance less predictable and fragments the JVM
   heap. In query engine, the information about the size of array we
   need to allocate is readily available during the optimization
   through cardinality estimation. Sometimes, we just use relation
   size as the approximation towards true cardinality and it works
   quite well in practice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use high-performance standard library.&lt;/strong&gt; Standard library is
   sometimes too generic for performance-critical use case. I used
   &lt;a href="https://javadoc.io/doc/it.unimi.dsi/fastutil/latest/index.html"&gt;fastutil&lt;/a&gt;
   in the query engine for specialized data structure like &lt;code&gt;IntSet&lt;/code&gt;.
   I found that fastutil’s specialized collections avoided the
   overhead of object pointers. Storing primitive keys in contiguous
   memory improved CPU cache hit rates and minimized pointer chasing
   during hash table probes. This tip also applies to the Rust
   prototype where we used HashMap and HashSet from
   &lt;a href="https://docs.rs/ahash/latest/ahash/index.html"&gt;ahash&lt;/a&gt; instead of
   the standard library to implement hash tables. Further, we used
   &lt;a href="https://docs.rs/memchr/latest/memchr/"&gt;memchr&lt;/a&gt; for string
   predicate evaluation instead of doing it ourselves.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use integer comparison instead of string comparison.&lt;/strong&gt; Initial
   implementation of the query engine assumed fairly generic queries
   as input workload. Specifically, the engine allowed two relations
   are joined on a string column, which didn’t show up in any
   benchmark that I have run. Thus I made the adjustment of assuming
   join only happens on a integer column (in fact, all the queries in
   the three benchmarks I run don’t even join on a composite
   key). This assumption simplified a lot of implementation and
   brought a significant performance improvement because string
   comparison is a lot slower than the integer comparison. (Papers
   like &lt;a href="https://dl.acm.org/doi/10.14778/3407790.3407797"&gt;this&lt;/a&gt;
   exploit the performance gap between string and integer comparison;
   see section 3.1.)  This is a good shortcut to take when building a
   research prototype.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use better JDBC.&lt;/strong&gt; This point is already mentioned in &lt;a href="#design"&gt;the prior
   section&lt;/a&gt; where C++ implementation of DuckDB JDBC driver
   has better performance than PostgreSQL JDBC driver implemented
   purely in Java.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Avoid repeated object creation (Object Pooling).&lt;/strong&gt; When
   &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; was implemented in an iterator form, backjumping was
   implemented in the form of message passing. The message itself was
   just an object to signal which relation should delete a tuple from
   its hash table. Instead of allocating a new message object for
   every backjump, I implemented a form of object reuse. This
   stabilized the heap usage and prevented frequent GC pauses from
   interrupting the query evaluation pipeline.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optimize performance on a small workload.&lt;/strong&gt; Running all three
    benchmarks with 120ish queries in a full-blown way takes multiple
    days. Doing so is inefficient if our goal is to optimize our
    prototype performance. A more ideal way to approach this is to
    sample a few queries from the workload and optimize the
    performance of those queries first. We can sample the queries in
    different ways such as by the number of relations appeared in the
    queries.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="departing-thoughts"&gt;Departing thoughts&lt;/h1&gt;
&lt;p&gt;Given the publication of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt;, I have always been asking
myself whether it is worthwhile spending five years pushing a work to
publication. Is it better to work on something else that doesn’t rely
on &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; so that I can have enough material to write a
thesis?  My answer right now is mixed. On one hand, research is all
about confidence and I think it is absolutely crucial for the first
research project to be successful so that a student can gain
confidence in continue pursuing the research path. The tricky thing is
about how to define success: for a senior professor who has published
hundreds of papers, whether a paper is published or not is no longer
relevant; for a PhD student just starting out, success means
publication. They need to see what research is publishable and gain
the reassurance that they can do it. It would require strong
confidence to not publish a result and instead continue building upon
it. From this perspective, I think it’s absolutely worth pushing a
research project to publication. Plus, we discovered new things along
the way such as acyclic convolution and the importance of optimizing
join tree for acyclic conjunctive query evaluation. On the other hand,
the algorithm of &lt;span class="math"&gt;\(\mathsf{TTJ}\)&lt;/span&gt; was finished in Summer 2021 and it was
just waste of time to try different things in the hope of getting the
badge that says “this work is published”. I think the takeaway from
all years of trying is to try to do some research that is completely
different from the field that the struggling manuscript concerns; by
working something completely different, the risk is diversified and it
is good for mental health.&lt;/p&gt;
&lt;h1 id="acknowledgements"&gt;Acknowledgements&lt;/h1&gt;
&lt;p&gt;I imagine this post serves as a sort of informal thesis. It would be a
shame if I did not give proper thanks to the many people who helped me
during my time at UT-Austin.&lt;/p&gt;
&lt;p&gt;Bailu Ding, Dixin Tang, and Marcelo Arenas provided various thoughtful
comments on the manuscript and valuable advice on how to push this
work toward publication. Greg Plaxton has been incredibly
understanding of my struggles and spent countless hours advising me on
all aspects of research–from navigating the PhD program to the
nuances of theory research. Juan Sequeda and Nathan Clement generously
shared their perspectives and experiences regarding their own PhD
journeys. Remy Wang was an indispensable force; he strengthened the
work significantly and helped push it across the finish line. Zhiting
Zhu has been a wonderful friend and someone I could always talk to
while I was away from my family in Austin. Finally, Sherry has
unconditionally supported my seemingly insane endeavor to continue
doing research after a challenging five years at UT-Austin.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;People call this algorithm Yannakakis algorithm, Yannakakis’
  algorithm, or Yannakakis’s algorithm. I think grammatically
  speaking, the most correct way is either Yannakakis’s algorithm
  or Yannakakis algorithm. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Acyclic conjunctive queries are everywhere; one may argue that
  many real life queries are in fact acyclic. See &lt;a href="https://arxiv.org/abs/2009.01769"&gt;this
  paper&lt;/a&gt; for a survey on
  acyclicity of many query workloads. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\mathsf{TT}1\)&lt;/span&gt; is slower than &lt;span class="math"&gt;\(\mathsf{TT}2\)&lt;/span&gt; by a factor of
  &lt;span class="math"&gt;\(\log n\)&lt;/span&gt; where &lt;span class="math"&gt;\(n\)&lt;/span&gt; is the number of variables in a dual
  constraint graph. However, &lt;span class="math"&gt;\(\mathsf{TT}1\)&lt;/span&gt; is much simpler than
  &lt;span class="math"&gt;\(\mathsf{TT}2\)&lt;/span&gt; and the number of variables in a constraint
  network is translated into the number of relations in a query,
  which is considered as a constant in a complexity model called
  data complexity where database instance is the problem input to
  a query evaluation algorithm. &lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;For a more in-depth discussion of the limitations of prose
proofs, see some writings
(&lt;a href="https://lamport.azurewebsites.net/pubs/rigor.pdf"&gt;1&lt;/a&gt;,
&lt;a href="https://lamport.azurewebsites.net/pubs/proof.pdf"&gt;2&lt;/a&gt;) by Leslie
Lamport. &lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 4 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;My friend’s PhD advisor once told him that it’s sufficient to
  have the software compile once just for the numbers; it’s okay
  that the software no longer functions once the paper is
  published. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 5 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2025"></category><category term="papers"></category><category term="my research"></category></entry><entry><title>Looking for Collaborators</title><link href="https://zhu45.org/posts/2024/Mar/24/looking-for-collaborators/" rel="alternate"></link><published>2024-03-24T20:11:00+08:00</published><updated>2024-03-24T20:11:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2024-03-24:/posts/2024/Mar/24/looking-for-collaborators/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#motivation"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#what-im-looking-for"&gt;What I’m looking for&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Quite often, I stumble upon personal websites from academia with sentence like “I’m always in search of collaborators”.
I figured I may try to write a sentence like that somewhere on my page as well. I think the most important reason for …&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#motivation"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#what-im-looking-for"&gt;What I’m looking for&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Quite often, I stumble upon personal websites from academia with sentence like “I’m always in search of collaborators”.
I figured I may try to write a sentence like that somewhere on my page as well. I think the most important reason for me is to 
have a chance to share experience and make friends along the way &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;; to people in academia, what’s more fun than talking about 
your research and working on some exciting ideas together? One question I have whenever I read a sentence like above is that:
how many people are actually reaching out? Does it work at all? I’m curious to find out myself.&lt;/p&gt;
&lt;h2 id="what-im-looking-for"&gt;What I’m looking for&lt;/h2&gt;
&lt;p&gt;Collaborator may look too serious. It’s great that we can have
something to work on together but I certainly don’t want to send those
people that may not know what collaborator mean or too afraid to reach
out to see what might happen. So, I plan to go extra miles here to
list out what I mean by the sentence “I’m always in search of
collaborators”.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;I’m looking for someone who I can talk about research. The topic can
  range from metadata of the research: research process, research
  story, etc, to concrete substance: actual research problems, details
  of some papers or technical matters. For metadata, I don’t have any
  preference; we can talk about anything you want to share or anything
  you want me to share. Effectively, we’re in the same therapy or
  support group. For the concrete substance, I do have preference
  because my knowledge is quite limited to some areas; sure, I’m okay
  with general computer science background but, to get into depth, I’m
  more comfortable talking about database (query processing, query
  optimization) and mechanism design (especially without money).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you are serious about collaborating on some research project, I
  hope you mean it. I usually work on at maximum two projects: one
  project is my ongoing project at school and the other project is the
  one we work together. Once I decide to investigate something, I’m
  usually very serious about it: I spend lots of time thinking and
  investigating the matter until I reach some form of a closure
  (hopefully, my other posts make the point).  I’m expecting you are
  too. It’s okay in general that you don’t have anything concrete to
  work on as long as you’re being accountable and truly want to do
  something together.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Please be patient. I hope you get that I’m still learning to do
  research. If you’re looking for someone that can guide you and crank
  out a paper in a short period of time, I’m not your guy. If you
  already have something and for some reason want my help, please be
  patient as I’m not a quick reaction person; if you talk to me about
  something that I haven’t investigated by myself, for sure I won’t
  understand it by my standard. But, don’t worry, you won’t feel like
  flying in the dark because I like to communicate very much and my
  preference way is through writing with talking based on my writing;
  that’s the key point of me looking for collaborator. I used to lead
  a reading group for undergraduates to provide them some research
  experience. I quickly find that they usually lack of patience
  because the project is not going anywhere and the feedback loop is
  less obvious than finishing a homework with clearly marked
  grades. So, if you feel lost, don’t worry; we’ll learn something
  along the way. Please let me know explicitly when you want to stop;
  being accountable, remember?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can check out my hobbies under the about page if you think those
  are good indicators to suggest whether we are a good match.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the idea looks promsing to you, please send me an email or send me
a request on &lt;a href="https://discord.gg/BrXgsAwS"&gt;discord&lt;/a&gt; (my username is
.zazk). We can move from there.&lt;/p&gt;
&lt;!-- It's been more than 3 years since my previous post. Probably, you have been aware that I'm doing my PhD in  --&gt;
&lt;!-- computer science at the University of Texas at Austin. The journey has been rough. If you search online about  --&gt;
&lt;!-- graduate school, phd and loneliness, you may be see a huge amount of results ranged from real life experience to  --&gt;
&lt;!-- scientific studies. To contribute to this theme and motivate the title about looking for collaborator(s) myself,  --&gt;
&lt;!-- I present my data points on why I feel loneliness in this journey. --&gt;
&lt;!-- The most dominant factor in my case is lack of interaction. Interaction comes from lots of places: your peers, your friends, and your advisors. Unfortunately, --&gt;
&lt;!-- I'm in a weird position that I don't have a lot of interactions from those sources. First of all, who I am contribute to this a lot.  --&gt;
&lt;!-- I'm an introvert person; putting myself out there for social purpose creates a lot of anxiety. However, that doesn't mean I'm against social;  --&gt;
&lt;!-- I'm very happy to meet with people sharing my hobbies including talking about research in a small setting where I can have more meaningful conversations. --&gt;
&lt;!-- Second, my age. I start graduate school in my late 20s and people in my age group start family and are busy with their careers. I start to sense a bit off-sync  --&gt;
&lt;!-- with the limited interactions with people in my program. Third, research environment. I'm the sole graduate student under my advisor, who is about to retire and  --&gt;
&lt;!-- doesn't meet with me a lot. In addition, not until very recently, the department recruited a new faculty that works on my research area. I have never been to a  --&gt;
&lt;!-- single conference due to lack of publication and funding. In addition, I think the design of the department doesn't foster enough collaboration. Consider the department floor plan below --&gt;
&lt;!-- ![UTCS floor plan]({static}/images/collaborator/utcs-floorplan.png) --&gt;
&lt;!-- Each floor is divided into two regions; each region is gated. I'm on the North side and the whole area is mostly empty. I can barely see  --&gt;
&lt;!-- anyone in the south tower because they are not on my path to my desk. I'll stop right here before this post looks like a vent; hopefully, you get the idea about loneliness. --&gt;
&lt;!-- I think I'm reaching a point that I need to talk with someone reguarly. When I was in industry, my social needs is mostly fulfilled by talking with colleagues within the same team. --&gt;
&lt;!-- especially in a large setting where I have to face a lots of strangers. --&gt;
&lt;!-- putting myself out there for social purpose creates a lot of anxiety. Usually, whenever I have free time, I  --&gt;
&lt;!-- enjoy being alone to recharge.  --&gt;
&lt;!-- .. prior experience --&gt;
&lt;!-- .. bin packing --&gt;
&lt;!-- .. introduction --&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;I think it helps to overcome loneliness in graduate school. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="2024"></category><category term="meta"></category></entry><entry><title>Release of sphinxcontrib-pseudocode</title><link href="https://zhu45.org/posts/2021/Dec/21/release-of-sphinxcontrib-pseudocode/" rel="alternate"></link><published>2021-12-21T02:11:00+08:00</published><updated>2021-12-21T02:11:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2021-12-21:/posts/2021/Dec/21/release-of-sphinxcontrib-pseudocode/</id><summary type="html">&lt;p&gt;To celebrate the release of &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode"&gt;sphinxcontrib-pseudocode&lt;/a&gt;, the 
first &lt;a href="https://www.sphinx-doc.org/en/master/"&gt;sphinx-doc&lt;/a&gt; extension I have ever written, I document some implementation 
details behind this extension. &lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation-details"&gt;Implementation Details&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#generating-unique-ids"&gt;Generating Unique IDs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#handling-js-scripts-and-code"&gt;Handling JS scripts and code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#support-references"&gt;Support References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#development-environment-setup"&gt;Development Environment Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;sphinxcontrib-pseudocode allows one to write &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt; &lt;a href="https://www.overleaf.com/learn/latex/Algorithms"&gt;algorithm&lt;/a&gt; 
(using &lt;code&gt;algpseudocode …&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;To celebrate the release of &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode"&gt;sphinxcontrib-pseudocode&lt;/a&gt;, the 
first &lt;a href="https://www.sphinx-doc.org/en/master/"&gt;sphinx-doc&lt;/a&gt; extension I have ever written, I document some implementation 
details behind this extension. &lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation-details"&gt;Implementation Details&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#generating-unique-ids"&gt;Generating Unique IDs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#handling-js-scripts-and-code"&gt;Handling JS scripts and code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#support-references"&gt;Support References&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#development-environment-setup"&gt;Development Environment Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;sphinxcontrib-pseudocode allows one to write &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt; &lt;a href="https://www.overleaf.com/learn/latex/Algorithms"&gt;algorithm&lt;/a&gt; 
(using &lt;code&gt;algpseudocode&lt;/code&gt; package, in specific) within sphinx-doc. The horsepower of doing so comes from 
&lt;a href="https://github.com/SaswatPadhi/pseudocode.js"&gt;pseudocode.js&lt;/a&gt;. The extension itself simply streamlines all the 
setup steps required by pseudocode.js and allows user to directly type &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt; algorithms within a sphinx-doc 
&lt;a href="https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html"&gt;directive&lt;/a&gt; &lt;code&gt;pcode&lt;/code&gt;, which is introduced
by this extension. The pseudocode.js specific html block and javascript (js) rendering code are automatically handled by the extension.
The rest of html generation steps, as usual, are done by sphinx-doc rendering engine.&lt;/p&gt;
&lt;p&gt;There aren’t many choices when coming to write algorithms within sphinx-doc. To my best knowledge, I only able to 
find &lt;a href="https://sphinx-proof.readthedocs.io/en/latest/syntax.html#algorithms"&gt;sphinx-proof&lt;/a&gt; that offers this cability.
However, I think sphinx-proof is suitable to write simple algorithms on very high level (e.g., I haven’t able to 
find a way to write explicitly for loop quite nicely using this extension). Thus, I think being able to write algorithm using &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt;
is a nice add-on in this niche territory. &lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;I built this extension based on &lt;a href="https://github.com/mgaitan/sphinxcontrib-mermaid"&gt;sphinxcontrib-mermaid&lt;/a&gt;. Thus, a plenty 
of boilerplate steps have been done (e.g., properly set up python package, etc). The major development effort is spent 
on modification to python files under &lt;code&gt;sphinxcontrib&lt;/code&gt; directory; in particular, 
&lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/master/sphinxcontrib/pseudocode.py"&gt;pseudocode.py&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To understand implementation details behind sphinxcontrib-pseudocode, we first need to understand how to use 
pseudocode.js. &lt;a href="https://github.com/SaswatPadhi/pseudocode.js/blob/master/README.md"&gt;README&lt;/a&gt; of pseudocode.js provides 
detailed steps. Here, I highlight some of the steps that are related to the implementation detailed later:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;After including the necessary js dependencies, we can embed our &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt; algorithm within a html block&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;pre&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"quicksort"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:hidden;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- our LaTeX algorithm --&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/pre&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To render the algorithm, we need to specify &lt;code&gt;id&lt;/code&gt; of the algorithm html block in the following js render code.
  In this example, the &lt;code&gt;id&lt;/code&gt; is &lt;code&gt;quicksort&lt;/code&gt;. We then need to put this render code at the end of the document.
  As shown in &lt;a href="https://github.com/SaswatPadhi/pseudocode.js/blob/master/static/footer.html.part"&gt;pseudocode.js example&lt;/a&gt;, 
  this piece of code sits right before we close &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag. If there are multiple algorithm blocks within a page, 
  we need to assign each block with an unique id and add corresponding &lt;code&gt;renderElement&lt;/code&gt; function call as well in the above 
  &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;pseudocode.renderElement(document.getElementById("quicksort"));
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pseudocode.js can take &lt;a href="https://github.com/SaswatPadhi/pseudocode.js#options"&gt;options&lt;/a&gt; that allow user to tweak rendering 
  behavior. As an example, we can pass in &lt;code&gt;lineNumber&lt;/code&gt; to a js render function to indicate we want to line numbering 
  the algorithm that the js render function associated with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;pseudocode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;renderElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;getElementById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"quicksort"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lineNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The usage of pseudocode.js exposes a few requirmenets we need to handle in our extension:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We need to assign unique &lt;code&gt;id&lt;/code&gt; to each algorithm block.&lt;/li&gt;
&lt;li&gt;Each algorithm block has to be associated with a &lt;code&gt;renderElement&lt;/code&gt; function, which itself may take extra options 
   that are supported by pseudocode.js (e.g., &lt;code&gt;lineNumber&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block that contains render functions needs to be placed at the bottom of html page.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="implementation-details"&gt;Implementation Details&lt;/h2&gt;
&lt;p&gt;Now, we start to detail the implementation idea behind sphinxcontrib-pseudocode and introduces a few concepts around 
writing extenstion to sphinx-doc rendering engine.&lt;/p&gt;
&lt;h3 id="generating-unique-ids"&gt;Generating Unique IDs&lt;/h3&gt;
&lt;p&gt;To generate unique &lt;code&gt;id&lt;/code&gt; to each algorithm block, I use 
&lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L62"&gt;uuid.uuid4()&lt;/a&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_node"&gt;add_node()&lt;/a&gt; is used to 
add a new Docutils node class to the sphinx-doc build system. During &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L168"&gt;this function call&lt;/a&gt;, we specify the &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L88"&gt;visitor function&lt;/a&gt; that can be used to render 
html code during the &lt;a href="https://www.sphinx-doc.org/en/master/extdev/index.html#build-phases"&gt;Phase 4 (Writing)&lt;/a&gt; of the sphinx-doc 
build phases &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;id&lt;/code&gt; created from &lt;code&gt;uuid&lt;/code&gt; are stored in Docutils node, which can then be referenced during sphinx-doc build phases. In specific,
we can reference &lt;code&gt;id&lt;/code&gt; attribute of the node to fill the id into the &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L72"&gt;html template&lt;/a&gt; 
so that sphinx-doc produces html algorithm block during the html generation.&lt;/p&gt;
&lt;h3 id="handling-js-scripts-and-code"&gt;Handling JS scripts and code&lt;/h3&gt;
&lt;p&gt;There are two parts that the extension needs to deal with js:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;We need to install pseudocode.js and its dependencies at the very beginning of the phase when Sphinx-doc needs to convert the parsed document 
   (i.e., a tree of Docutils nodes) into an output format (i.e., html). This is because we need to let Sphinx-doc includes those necessary js scripts 
   at the beginning of the html document being produced. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We also want to create corresponding pseudocode.js render function calls so that all the algorithm html blocks can be rendered properly. That means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we need to fill those function calls with &lt;code&gt;id&lt;/code&gt;s we just created&lt;/li&gt;
&lt;li&gt;create the exact same number of render functions as the number of algorithm blocks &lt;/li&gt;
&lt;li&gt;able to pass in specific options if a &lt;code&gt;pcode&lt;/code&gt; &lt;a href="https://www.sphinx-doc.org/en/master/extdev/markupapi.html#directives"&gt;directive&lt;/a&gt; 
  contains specific options&lt;/li&gt;
&lt;li&gt;put those js functions at the end of html document&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s talk about each part in more details. The core concepts from sphinx-doc to our implementation are &lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx-core-events"&gt;events and associated events handlers&lt;/a&gt;.
Essentially, sphinx-doc will emit different events during its build phase and our extension can register associated event handlers to perform certain tasks 
when certain events happened. &lt;/p&gt;
&lt;p&gt;The first important event is &lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#event-builder-inited"&gt;builder-inited&lt;/a&gt;. This is the time when 
we need to &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L173"&gt;supply&lt;/a&gt; pseudocode.js and its dependencies. 
&lt;a href="https://www.sphinx-doc.org/en/master/extdev/index.html#important-objects"&gt;Builder&lt;/a&gt; is the object that takes care of converting the parsed document into an output format. 
In specific, we use &lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_js_file"&gt;add_js_file&lt;/a&gt; to add pseudocode.js. We also 
&lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L132"&gt;add&lt;/a&gt;
&lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_css_file"&gt;css files&lt;/a&gt; as well &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;builder-inited&lt;/code&gt; event happens, the document has been parsed yet. This means sphinx-doc 
doesn’t encounter our &lt;code&gt;pcode&lt;/code&gt; directives yet. Thus, the number of algorithm blocks are unknown.
Thus, we cannot generate render functions at this time.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There is one limitation about sphinx-doc that shapes how we handle part 2. That is, to my best knowledge, sphinx-doc doesn’t provide 
a way to insert &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; right before &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag close (as stated in pseudocode.js usage guide) during the build. This means,
all js related elements (depenendent scripts, js function calls) have to appear at the very beginning of the document. In my experiment
with pseudocode.js, directly following example usage (i.e., &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; block with &lt;code&gt;renderElement&lt;/code&gt; calls) cannot render the algorithm 
blocks successfully. I’m no javascript expert but as suggested by multiple sources (&lt;a href="https://stackoverflow.com/questions/38860740/alternative-for-executing-script-at-end-of-document-body"&gt;1&lt;/a&gt;,
&lt;a href="https://stackoverflow.com/questions/436411/where-should-i-put-script-tags-in-html-markup"&gt;2&lt;/a&gt;), I can use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event"&gt;DOMContentLoaded&lt;/a&gt;
to make pseudocode.js render functions work properly after the whole html document is loaded. As a result, I can put all the js elements at the 
beginning of the html document.&lt;/p&gt;
&lt;p&gt;My implementation for part 2 follows &lt;a href="https://github.com/hagenw/sphinxcontrib-katex/blob/ce89a95b3b330a19ad4562b87aacc69ddb6742f2/sphinxcontrib/katex.py#L185"&gt;sphinxcontrib-katex&lt;/a&gt; closely.
The very first thing to do is to gather all &lt;code&gt;id&lt;/code&gt;s we have created so that we know how many &lt;code&gt;renderElement&lt;/code&gt; function calls we need. We do so when 
&lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#event-doctree-resolved"&gt;doctree-resolved&lt;/a&gt; event happens. When this event happens, the 
parse tree of Docutils node (i.e., doctree) has been created. Thus, we can access all &lt;code&gt;pcode&lt;/code&gt; nodes. I follow &lt;a href="https://www.sphinx-doc.org/en/master/development/tutorials/todo.html"&gt;TODO extension example&lt;/a&gt;
to &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L143"&gt;traverse the doctree and collect ids&lt;/a&gt;.
In addition to ids, we also any options that each &lt;code&gt;pcode&lt;/code&gt; directive specifies.&lt;/p&gt;
&lt;p&gt;Once we have collected ids and options, we can generate a js script called &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L101"&gt;katex_autorenderer.js&lt;/a&gt;,
which contains all &lt;code&gt;renderElement&lt;/code&gt; function calls. As an example, it looks like &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;addEventListener&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"DOMContentLoaded"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;function&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;pseudocode.renderElement(document.getElementById("37667c0e-b9e7-489f-b48e-d64117042cd2"),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lineNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;pseudocode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;renderElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;getElementById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"37c7acbe-a36a-4260-a464-9fd6bff71a3c"&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;lineNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;pseudocode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;renderElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;getElementById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2bace0ba-4113-4766-b226-13c7a6456925"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;pseudocode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;renderElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;getElementById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"bb8f4069-52bd-48d0-b782-9d4b0038f2ec"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;pseudocode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;renderElement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;getElementById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"6f8008db-5388-46c6-938e-837c763d7ed9"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;We cannot register &lt;code&gt;katex_autorenderer.js&lt;/code&gt; at &lt;code&gt;doctree-resolved&lt;/code&gt; event but we can do so instead at &lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#event-html-page-context"&gt;html-page-context&lt;/a&gt;. 
That’s where &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/208034f7b9f3241f93712d25ec037961c98d65d3/sphinxcontrib/pseudocode.py#L149"&gt;install_js2_part2&lt;/a&gt; comes from: 
we have to split js generation and js registration in two phases.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="support-references"&gt;Support References&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Support since 0.5.0&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One important feature is to allow one easily reference the algorithm written in &lt;code&gt;pcode&lt;/code&gt; directive. 
As documented in &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/issues/8"&gt;this issue&lt;/a&gt;, 
there are two considerations on how to implement this feature:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Like &lt;a href="https://www.sphinx-doc.org/en/master/development/tutorials/recipe.html"&gt;recipe extension example&lt;/a&gt;, we can add
   special reference role like &lt;code&gt;:recipe:ref:&lt;/code&gt; to reference any paritcular algorithm.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alternatively, just like figure, table, or sections, we can use 
   &lt;a href="https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-numref"&gt;numref&lt;/a&gt; role to reference 
   &lt;code&gt;pcode&lt;/code&gt; directives as well.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I use the 2nd option. To implement such feature, we need to leverage &lt;a href="https://www.sphinx-doc.org/en/master/extdev/appapi.html#sphinx.application.Sphinx.add_enumerable_node"&gt;add_enumerable_node&lt;/a&gt; API. To understand how to use it, let’s take a closer look at how &lt;code&gt;:numref:&lt;/code&gt; works with figure. 
Suppose, in &lt;code&gt;rst&lt;/code&gt; document, I have &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="nt"&gt;_l7-fig2.3:&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; /_static/linear-programming/l7-fig2.3.png

   A toy example of LP
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code is rendered as &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;figure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"align-default"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"id13"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"l7-fig2-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"../_images/l7-fig2.3.png"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"../_images/l7-fig2.3.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;figcaption&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"caption-number"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fig.&lt;span class="w"&gt; &lt;/span&gt;97&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"caption-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;A&lt;span class="w"&gt; &lt;/span&gt;toy&lt;span class="w"&gt; &lt;/span&gt;example&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;LP&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"headerlink"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#id13"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Permalink to this image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;¶&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/figcaption&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/figure&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;id13&lt;/code&gt; is the numbering automatically incremented by &lt;code&gt;add_eumerable_node&lt;/code&gt; API. &lt;code&gt;l7-fig2-3&lt;/code&gt; is the reference label, which 
has to be unique. Then the structure of the HTML code is: &lt;code&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; corresponds to &lt;code&gt;figure::&lt;/code&gt; directive and 
&lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; is the actual content (i.e., image) of the directive. Caption indicated by &lt;code&gt;&amp;lt;figcaption&amp;gt;&lt;/code&gt; follows content immediately.
Thus, in practice, we use three docutils nodes to correspond these three components (directive, content, caption). 
The best way to learn how to use &lt;code&gt;add_enumerable_node&lt;/code&gt; is to study 
&lt;a href="https://github.com/sphinx-contrib/stuffcounter"&gt;stuffCounter&lt;/a&gt; code repository. &lt;/p&gt;
&lt;p&gt;In fact, as shown by &lt;a href="https://github.com/hnakamur/sphinx-deb/blob/34e8fa6013e0567f12eabfd4f71e7a82ce63394e/tests/roots/test-add_enumerable_node/enumerable_node.py"&gt;this code&lt;/a&gt;, there is a much simpler way to use &lt;code&gt;add_eumerable_node&lt;/code&gt; API if the directive has a required caption option. Then, we can directly pass a &lt;a href="https://github.com/hnakamur/sphinx-deb/blob/34e8fa6013e0567f12eabfd4f71e7a82ce63394e/tests/roots/test-add_enumerable_node/enumerable_node.py#L61"&gt;caption getter function&lt;/a&gt; to the API. The reason we need to use three nodes implementation style is that we want to set &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt; algorithm numbering 
the same as &lt;code&gt;pcode&lt;/code&gt; reference numbering. As an example, suppose we have the code &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="nt"&gt;_dummy-algorithm:&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;pcode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;

    \begin{algorithm}
    \caption{Dummy Algorithm}
    \begin{algorithmic}
    \PRINT \texttt{'hello world'}
    \end{algorithmic}
    \end{algorithm}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, it will be rendered as &lt;/p&gt;
&lt;p&gt;&lt;img alt="render of the above pcode block" class="img-responsive" src="https://zhu45.org/images/sphinxcontrib-pseudocode/dummy-algorithm.png"/&gt;&lt;/p&gt;
&lt;p&gt;The algorithm has numbering 1. Then, when we reference the algorithm via &lt;code&gt;:numref:`dummy-algorithm&lt;/code&gt;, we want to have “Algorithm 1” rendered in 
HTML as well. To do so, we extract the numeric part from id of the directive (e.g., &lt;code&gt;13&lt;/code&gt; in &lt;code&gt;id13&lt;/code&gt; in the figure HTML example) and use 
&lt;code&gt;captionCount&lt;/code&gt; option offered by pseudocode.js to manually set &lt;span class="math"&gt;\(\LaTeX\)&lt;/span&gt; numbering.&lt;/p&gt;
&lt;h2 id="development-environment-setup"&gt;Development Environment Setup&lt;/h2&gt;
&lt;p&gt;To concludes this post, I describe the setup I have for extension development. I reference &lt;a href="https://techwriter.documatt.com/2021/debug-sphinx-extension.html"&gt;this post&lt;/a&gt; 
and &lt;a href="https://gitlab.com/Molcas/OpenMolcas/-/blob/master/doc/source/conf.py#L34"&gt;code&lt;/a&gt; for my setup. Here is my configuration in PyCharm&lt;/p&gt;
&lt;p&gt;&lt;img alt="pycharm configuration setup" class="img-responsive" src="https://zhu45.org/images/sphinxcontrib-pseudocode/pycharm-setup.png"/&gt;&lt;/p&gt;
&lt;p&gt;The central idea is to run/debug &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/tree/master/docs"&gt;demo docs&lt;/a&gt; using &lt;code&gt;sphinx-build&lt;/code&gt;. 
Since the whole project is organized as a python package, we need to modify &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode/blob/546756083b2c2d0aa2a5dff817a9e6a472369b5a/docs/conf.py#L31"&gt;conf.py&lt;/a&gt;
to allow the demo docs to automatically find the extension source code but not via python package installation. &lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That’s all I have to say about implementing &lt;a href="https://github.com/xxks-kkk/sphinxcontrib-pseudocode"&gt;sphinxcontrib-pseudocode&lt;/a&gt;. Hope 
this post becomes useful when you build your own extension to sphinx-doc.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;You can also see the explanation in the &lt;a href="https://www.sphinx-doc.org/en/master/development/tutorials/todo.html"&gt;“TODO” extension&lt;/a&gt; 
  provided by sphinx-doc. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;I also reference how sphinx-doc &lt;a href="https://github.com/sphinx-doc/sphinx/blob/7d7c59aaf22f110bfc7ed5a1385e6865ccf327fa/sphinx/ext/mathjax.py#L73"&gt;installs MathJax.js&lt;/a&gt; for this part. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2021"></category><category term="sphinx-doc"></category></entry><entry><title>Build My First PC</title><link href="https://zhu45.org/posts/2021/Sep/29/build-my-first-pc/" rel="alternate"></link><published>2021-09-29T02:11:00+08:00</published><updated>2021-09-29T02:11:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2021-09-29:/posts/2021/Sep/29/build-my-first-pc/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#requirement"&gt;Requirement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#motherboard"&gt;Motherboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cpu"&gt;CPU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cpu-cooler"&gt;CPU Cooler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#graphics-card"&gt;Graphics Card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#storage-drive"&gt;Storage Drive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ram"&gt;RAM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#power-supply-unit-psu"&gt;Power Supply Unit (PSU)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#pc-chassis"&gt;PC Chassis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#tools"&gt;Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#my-choice"&gt;My Choice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;This page contains my note on how to build a PC.&lt;/p&gt;
&lt;h2 id="requirement"&gt;Requirement&lt;/h2&gt;
&lt;p&gt;I use this PC mostly for research. The requirement is listed below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Large memory. 32GiB at least …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#requirement"&gt;Requirement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#motherboard"&gt;Motherboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cpu"&gt;CPU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cpu-cooler"&gt;CPU Cooler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#graphics-card"&gt;Graphics Card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#storage-drive"&gt;Storage Drive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ram"&gt;RAM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#power-supply-unit-psu"&gt;Power Supply Unit (PSU)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#pc-chassis"&gt;PC Chassis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#tools"&gt;Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#my-choice"&gt;My Choice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;This page contains my note on how to build a PC.&lt;/p&gt;
&lt;h2 id="requirement"&gt;Requirement&lt;/h2&gt;
&lt;p&gt;I use this PC mostly for research. The requirement is listed below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Large memory. 32GiB at least and with support to expand to 64GiB. This requirement 
  is for building large software projects fast enough. In addition, large memory allows 
  me to work on in-memory/distributed database development and benchmarking.&lt;/li&gt;
&lt;li&gt;Support for video editing. Streaming support is optional but good to have.&lt;/li&gt;
&lt;li&gt;Gaming support is not a top priority.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;p&gt;I haven’t built a PC before. This section documents background knowledge helping me 
make decisions on picking parts.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Components not need to research and purchase this time: monitor, keyboard, mouse.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="motherboard"&gt;Motherboard&lt;/h3&gt;
&lt;p&gt;Motherboard connects graphics cards, RAM, the CPU, power supply, and storage drives to allow them interact with each other.&lt;/p&gt;
&lt;p&gt;Criteria to consider when choosing a motherboard:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compatibility with other parts, most notably with CPU (CPU socket type), and overclocking support&lt;/li&gt;
&lt;li&gt;Number of &lt;strong&gt;&lt;a href="https://artofpc.com/motherboard-connectors-and-components/"&gt;DIMM (Dual In-Line Memory Module) Slots&lt;/a&gt;&lt;/strong&gt; (i.e., memory slots, RAM slots).&lt;/li&gt;
&lt;li&gt;M.2 compatability&lt;/li&gt;
&lt;li&gt;PCIe generation &lt;/li&gt;
&lt;li&gt;PCIe slot size&lt;/li&gt;
&lt;li&gt;Motherboard form &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CPU compatibility varies greatly between motherboards, since different generations and brands of processors feature different chipsets and socket types&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;chipset&lt;/strong&gt;: term used to describe a specific hardware configuration of a motherboard. All motherboards with the same chipset have a certain group of features in common, such as the same CPU socket, 
  PCIe generation supported, RAM generation supported, and overclockability. For example, within Intel’s motherboard 500-series there are currently four different chipsets: H510, B560, H570, and Z590. 
  These all have different features, such as different numbers of PCIe lanes, different USB and SATA port counts, and different overclockability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;socket type&lt;/strong&gt;: refers to CPU socket type. CPU socket houses CPU and all major components are connected to the CPU socket. For example, Intel’s 400 and 500-series motherboard has a LGA 1200 socket, 
  which supports Intel’s 10th and 11th generation CPU.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;AM4 has been the standard socket type for AMD since the introduction of their 1000 series (Zen 1) CPUs in early 2017. Additionally, 500-series motherboards are not compatible with 1000 or 2000 series CPUs, 
  despite having the same socket type. Intel’s 8th and 9th generation CPUs are only compatible with 300-series motherboards (known as LGA 1151 Revision 2), while 6th and 7th generation CPUs will only work with 100 and 200-series.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ensure motherboard has &lt;a href="https://artofpc.com/motherboard-connectors-and-components/"&gt;M.2 slots&lt;/a&gt; &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; if deciding to use M.2 storage drive. If a motherboard supports PCIe gen 4, it will usually have at least one M.2 slot that also 
  supports gen 4. This allows for extremely fast data transfer speeds with a gen 4 SSD. Also, make sure to check the bus type supported by the slot (e.g., SATA bus or PCIe bus). &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PCIe generation: Newer versions of PCIe have higher bandwidth, which translates to better performance. For example, PCIe 4th generation (the newest revision) has twice the bandwidth of PCIe gen 3. However, besides motherboard 
  PCIe generation support, we also need to check if CPU PCIe generation support. Let’s say we have a PCIe gen 4 SSD. For it to transfer data at gen 4 speeds, both the CPU and the motherboard must support 4th-generation PCIe as well. 
  Otherwise the storage drive will only run at gen 3 speeds (PCIe is backwards compatible).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PCIe slots have different sizes: typically, x1, x4, x8, and x16. For example, “PCIe 3.0 x4” refers to a Gen 3 expansion card or slot with a four-lane configuration. 
  The bigger the size, the more lanes the slot supports. CPUs support only a limited number of PCIe lanes, and the quantity varies between models. A PCIe x16 slot, 
  for example, uses 16 of these lanes, while a PCIe x4 slot uses only four. Different components use different numbers of lanes. For instance, discrete graphics cards use 16, while PCIe SSDs use four apiece. 
  Also, since number of PCIe lanes that CPU + motherboard support is fixed, some slots share lanes whereas other slots may have dedicated ports. &lt;a href="https://www.reddit.com/r/buildapc/comments/81gdns/how_do_i_know_if_my_m2_slots_support_nvme/"&gt;See this reddit’s post as an example&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check whether motherboard support PCI Express NVMe drives in the BIOS for the drive to act as a bootable device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are three types of motherboard:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ATX&lt;/strong&gt;: This is the full-sized motherboard, and comes with multiple PCIe slots and four RAM slots. It costs more and takes up more space than the other two sizes, but in exchange allows for greater customizability; 
  you can have more RAM and run dual graphics cards if desired.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Micro-ATX&lt;/strong&gt;: This is the mid-sized motherboard. It is generally cheaper than its smaller counterpart, and comes complete with two to four RAM slots and one PCIe slot. This should be enough for just about any PC build, 
  since theoretically you could have 128GB of RAM and just about any graphics card.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mini-ITX&lt;/strong&gt;: This is the smallest motherboard, but it’s typically more expensive than a Micro-ATX. It is usually only used when you need to fit your PC in a very tight compartment.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cpu"&gt;CPU&lt;/h3&gt;
&lt;p&gt;CPU controls every other component and sends instructions to the rest of system.&lt;/p&gt;
&lt;p&gt;Criteria to consider when choosing a CPU:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If not having a separate graphics card, CPU needs to have integrated graphics.&lt;/li&gt;
&lt;li&gt;CPU tiers&lt;/li&gt;
&lt;li&gt;CPU designations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There are two main brands to choose from: Intel and AMD. There are many generations of CPU’s (Intel is on its 11th generation, and AMD’s Ryzen processors are on their 5th). However, the most important is the CPU tiers. There are 
  four main categories to choose from:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 3-tier: Intel’s Core i3 and AMD’s Ryzen 3 processors. These are the cheapest processors, but also the least powerful. These are typically the best choice if you’re looking to build a PC for basic office-type functions. 
    They’re also great for budget gaming; recent i3 and Ryzen 3 processors like the i3-10100 and Ryzen 3 3100 can easily run AAA games at upwards of 144FPS, making them ideal for budget gaming rigs.&lt;/li&gt;
&lt;li&gt;The 5-tier: Intel’s Core i5 and AMD’s Ryzen 5 processors. These are considered by many to be the ideal gaming processors; they’re not as expensive as an 7 or 9 category, but get similar in-game performance. An i5 or Ryzen 5 
    is good if you’re looking to build a high-mid tier gaming rig, or if you need to run office-type software (like word processors, Internet browsers, or spreadsheets) at maximum speed.&lt;/li&gt;
&lt;li&gt;The 7-tier: Intel’s Core i7 and AMD’s Ryzen 7 processors. These are extremely powerful processors and are capable of running games at very high framerates when paired with a good graphics card, and capable of running many 
    programs at the same time with no trouble. Suitable for doing things like video editing that will require more cores. They may also be the best option for you if you plan on having a very large number of programs running 
    simultaneously.&lt;/li&gt;
&lt;li&gt;The 9-tier: Intel’s Core i9 and AMD’s Ryzen 9 processors. These are the most powerful CPUs available, and consequently the most expensive.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU Designations: some CPUs have a letter tacked on at the end (e.g., i7-11700K, Ryzen 3 3200G). These letters at the end of the model denote certain traits. The most common processor suffixes are listed below: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(intel) K: means that a specific processor is unlocked, and able to be overclocked. Intel processors are locked by default, and are not overclockable unless they are a “K” model.&lt;/li&gt;
&lt;li&gt;(intel) F: means that a processor requires discrete graphics to operate. Intel processors come with integrated graphics by default, but F-designated processors lack this feature, and need a graphics card to generate an image.&lt;/li&gt;
&lt;li&gt;(intel) T: These processors are power-optimized, and generate much less heat than their standard counterparts. They’re also less powerful.&lt;/li&gt;
&lt;li&gt;(ryzen) G: means that the processor has integrated graphics. These are also known as APUs, or Accelerated Processing Units.&lt;/li&gt;
&lt;li&gt;(ryzen) X: means that the processor is has a slightly faster factory clock speed than its non-X counterpart. For example, the Ryzen 5 3600x is slightly faster than the Ryzen 5 3600. In other words, 
  it’s overclocked out of the box.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some pointers for performance comparison: &lt;a href="https://www.tomshardware.com/reviews/cpu-hierarchy,4312.html"&gt;Tom’s Hardware CPU Benchmarks and Performance Hierarchy Charts&lt;/a&gt;, &lt;a href="https://artofpc.com/amd-vs-intel-cpu-value-comparison-2021/"&gt;AMD vs. Intel: CPU Value Comparison (2021)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="cpu-cooler"&gt;CPU Cooler&lt;/h3&gt;
&lt;p&gt;A CPU generates a massive amount of heat, and without proper cooling it will throttle and shut down. A CPU cooler helps avoid this by dissipating heat away from the surface of the CPU and blowing it somewhere else, typically the case.
From there the air is blown out by case fans, keeping components temperatures low. &lt;strong&gt;Thermal paste&lt;/strong&gt; is applied between the cooler and CPU helps the cooler remove heat from the CPU and keep it from overheating.&lt;/p&gt;
&lt;p&gt;Two types of cooling systems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Air coolers&lt;/strong&gt;: They typically use a combination of a metal heatsink and fan(s) to move heat away from the CPU. All Intel and AMD stock coolers (coolers that come with the CPU) are air coolers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Water coolers&lt;/strong&gt;: formally called &lt;strong&gt;all-in-one (AIO)&lt;/strong&gt; water coolers. These systems use a constantly cycling loop of water to cool the CPU. Cool water runs by the processor, and heats up as the CPU transfers heat to it. 
  It continues around the loop and is cooled by a radiator, and the cycle continues. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Criteria to consider when choosing a CPU Cooler:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cooler’s &lt;strong&gt;Thermal Design Power (TDP)&lt;/strong&gt; rating.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Unless you plan to overclock your CPU (boost the speed it runs at to get better performance from it), the default cooler that comes with your processor should be more than adequate. 
  Most high-end processors don’t come with one though.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cooler’s TDP rating: TDP actually refers to the amount of heat that a component puts out, but coolers are rated based on how much heat they are able to disperse. A cooler with a TDP of 250W, then, should be able to keep a CPU 
  with a TDP of 250W cool. For reference, the large majority of CPUs are 125W or lower, so a 250W cooler is very powerful. Thus, look up your CPU’s TDP and buy a cooler that can handle that amount of heat. This is only if 
  you bought a high-end processor, or if you’re looking to overclock yours.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="graphics-card"&gt;Graphics Card&lt;/h3&gt;
&lt;p&gt;Graphics card is also called GPU (Graphics Processing Unit) or video card, renders the images on the screen.&lt;/p&gt;
&lt;p&gt;Criteria to consider when choosing a graphics card:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Synergy between CPU and graphics card to prevent bottlenecking&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You won’t need a graphics card for basic office utilities, but for things like gaming, 3D rendering, and high-resolution video editing it’s essential to have a graphics card.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The best way to decide on your ideal graphics card is to look up benchmarks and figure out what card will meet your needs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Designations: Graphics cards sometimes have suffixes added to the end of them, which denote better performance than the standard version. For Nvidia, these include “Ti” and “Super”, while Radeon cards 
  use “XT.” For example, a 1660 Ti or 1660 Super is better than a regular 1660, and a Radeon 5700XT is better than a 5700. In general, “Ti” cards tend to be marginally better than their “Super” counterparts, 
  but the difference is typically negligible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bottlenecking: If you buy a CPU that is significantly more powerful than your GPU, or vice versa, this can result in a CPU or GPU bottleneck. What this means is that one piece of hardware is maxing out while 
  the other is not using close to its full potential. You’d be better off buying a more powerful CPU and spending a little less on your graphics card, since this way you will get more frames per second at the same cost.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Performance benchmarks: &lt;a href="https://www.tomshardware.com/reviews/gpu-hierarchy,4388.html"&gt;Tom’s Hardware GPU Benchmarks and Hierarchy 2021: Graphics Cards Ranked&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tools: &lt;a href="https://www.gpucheck.com/cpu-benchmark-comparison"&gt;Compare PC Processort + Graphics Card benchmarks&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="storage-drive"&gt;Storage Drive&lt;/h3&gt;
&lt;p&gt;The storage drive(s) in determine computer’s storage capacity. There are two main types of drive: HDD and SSD. Furthermore, the SSD category is broken into 2 types of its own: NVMe and SATA.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HDD&lt;/strong&gt;: HDD stands for Hard Disk Drive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSD&lt;/strong&gt;: SSD stands for Solid State Drive. SSD retreives information much faster than HDD. Cost more than HDD.&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SATA&lt;/strong&gt;: SATA stands for Serial Advanced Technology Attachment, and refers to the motherboard port that SATA SSDs plug into.
  These SSDs are slower than their NVMe counterparts, but still much faster than traditional hard drives.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NVMe&lt;/strong&gt;: NVMe stands for Non-Volatile Memory Express. More than 5 times faster than most SATA SSDs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Criteria to consider when choosing storage drives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;storage capacity &lt;/li&gt;
&lt;li&gt;SSD vs. HDD&lt;/li&gt;
&lt;li&gt;SATA vs. NVMe&lt;/li&gt;
&lt;li&gt;Compatibility with motherboard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;NVMe drive: check read/write speeds, PCIe generation and its compatibility with motherboard slots (e.g., M.2 Slot with PCI4 gen 4 works best with PCIe gen 4 NVMe drive)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;M.2 slots may have following specification “2242/2260/2280/22110 M-key”, “2242” indicates the size of SSD that M.2 slot supports: 22 width in millimeters and 42 length in millimeters. 
  M-key means M.2 slot supports M.2 SSD with M-key. An M.2 SSD with M key doesn’t fit in a motherboard with only B key and vice versa. The key is also relevant to the speed: SSDs with an M key can handle a 
  higher speed than versions with a B key. More detailed explanation in &lt;a href="https://www.dell.com/support/kbdoc/en-us/000144170/how-to-distinguish-the-differences-between-m-2-cards"&gt;Dell KB&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ram"&gt;RAM&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;RAM&lt;/strong&gt; stands for Random Access Memory, and the amount of RAM you buy will determine how much temporary data you can store for near-instant access. &lt;/p&gt;
&lt;p&gt;Criteria to consider when choosing RAM:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DDR Type &lt;/li&gt;
&lt;li&gt;Capacity &lt;/li&gt;
&lt;li&gt;Speed &lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DDR4 is the latest RAM technology and is about twice as fast as its predecessor DDR3. DDR3 can no longer with modern motherboards.&lt;/li&gt;
&lt;li&gt;All RAM modules come with an advertised clock speed. 3200MHz (3200 cycles per second) is the sweet spot in price to performance. We recommend this for the majority of users. 
  If you opt for a Ryzen processor you may benefit from faster RAM. 3600MHz is probably your best bet in this scenario. &lt;/li&gt;
&lt;li&gt;Generally in the RAM’s product description or product title, we can see a number that reflects the &lt;strong&gt;CAS latency&lt;/strong&gt;. It will usually be written as “Cxx” or “CLxx”. C16 or less is ideal; you’ll find 
  that the majority of 3200MHz RAM is C16. Realistically, you won’t notice the difference in any RAM below 20, but don’t buy memory with a latency higher than that.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="power-supply-unit-psu"&gt;Power Supply Unit (PSU)&lt;/h3&gt;
&lt;p&gt;PSU is computer’s power source. It directs electricity from a wall outlet to a computer’s motherboard, where it can be distributed to all of the components as needed. &lt;/p&gt;
&lt;p&gt;Criteria to consider when choosing a PSU:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wattage&lt;/li&gt;
&lt;li&gt;Modularity &lt;/li&gt;
&lt;li&gt;Brand&lt;/li&gt;
&lt;li&gt;Efficiency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Wattage: when choosing a power supply, the primary consideration should be its wattage. The safest method is to use &lt;a href="https://www.newegg.com/tools/power-supply-calculator/"&gt;NewEgg’s Power Supply calculator&lt;/a&gt; or a similar 
  tool to see exactly how much power your system will drain. Multiply this number by 1.3 and then round up to the next multiple of 50. That’s the power supply wattage you want. Example, if Newegg’s estimates that total system 
  wattage will be 600W, then we buy 800W PSU (&lt;span class="math"&gt;\(600 * 1.3\)&lt;/span&gt; and round up to the nearest multiple of 50). This is a good rule of thumb to use in order to account for any sudden spikes in energy usage that may occur. Most calculators 
  estimate based on a component’s power draw at low usage, rather than at max load. Ten times out of ten, you’ll be better off having too much power rather than too little.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modularity: Modularity means, essentially, the customizability of a power supply. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fully modular means that every single power cable can be removed, allowing you to only use cables that are needed. &lt;/li&gt;
&lt;li&gt;Non-modular power supplies have all of the cables built-in, and you are unable to remove them. This means that, with non-modular power supplies, you will probably end up having excess cables that aren’t 
  connected to anything that are still taking up space in your case. The only benefit is that non-modular PSU’s are cheaper.&lt;/li&gt;
&lt;li&gt;Semi-modular (a hybrid between non-modular and fully modular) is recommended and most practical: The essential cables, such as the &lt;a href="https://artofpc.com/motherboard-connectors-and-components/"&gt;ATX cable&lt;/a&gt; &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt; that powers 
  your motherboard and your CPU cable, are built in. Other cables like the 8-pin used for most graphics cards are modular, so you can use them if needed, but not have extra unused cables in your case.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Brand: recommend EVGA or Corsair PSUs. Cheaply-built power supply has the potential to ruin the rest of your components, start a fire, and generally wreak havoc on your system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Efficiency is measured by “80-Plus” rating. When a PSU sends power to your computer, some percentage of the power from your outlet never reaches the computer, and is instead released as heat. 
  The more heat is released, the less power reaches the computer and the less efficient the PSU is. If 18% of the total wattage coming from the wall is lost in transit to your PC, your PSU is 82% efficient, and thus would earn a 
  Bronze rating. See &lt;a href="https://i1.wp.com/www.maketecheasier.com/assets/uploads/2019/02/what-is-80-plus-specification-table-2-e1551232843557.png?w=1200&amp;amp;ssl=1"&gt;80-Plus rating chart&lt;/a&gt;. Normally, stick to Bronze rating unless 
  the maginal efficiency improvement (efficiency improved / cost difference) is significant. For example, 9% jump in efficiency at full load with $75 cost more, it would take nearly 10,000 hours, or over a year, of your computer 
  running at full speed to save the $75 extra you spent on the Titanium (assuming a $.12/kwh electricity cost).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="pc-chassis"&gt;PC Chassis&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Chasis&lt;/strong&gt; (also called case, tower) holds all of the components inside, and is the hub to which user connects almost all external cables. These include display cables like HDMI and DisplayPort, USB connectors, 
Ethernet cables, audio jacks, and more. Computer cases come in three main sizes: &lt;strong&gt;Full tower&lt;/strong&gt;, &lt;strong&gt;Mid tower&lt;/strong&gt;, and &lt;strong&gt;Mini tower&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;Criteria to consider when choosing a case:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need&lt;/li&gt;
&lt;li&gt;Case with fans (=&amp;gt; good airflow)&lt;/li&gt;
&lt;li&gt;Compatibility between case and motherboard&lt;/li&gt;
&lt;li&gt;Cable management (less important)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Detailed notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Unless you need to store your computer in a very small compartment, Mid or Full towers are the best option. If you get a Mini tower you’ll probably need to get a smaller form-factor ITX motherboard, 
  which will cost you more money than a standard one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you need a case with a CD/DVD tray, SD card reader, or anything else specific make sure to ensure that the one you order has those features. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Look for a case that comes with fans installed, as this will help keep your entire system cool and allow for good airflow. Ideally, you’ll have at least one in both the front and back. Alternatively, you can buy extra system 
  fans if your case is compatible. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure getting a case with a good airflow. This requires actually taking a detailed look at case or its pictures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cases will have a set list of motherboard types they support so, for example, a smaller case probably won’t support a full-sized ATX motherboard.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tools"&gt;Tools&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pcpartpicker.com/list/"&gt;PC Part Picker&lt;/a&gt; to perform compatibility check on parts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="my-choice"&gt;My Choice&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CPU: &lt;a href="https://amzn.to/3zQ0n7g"&gt;AMD Ryzen 9 5900X 3.7 GHz 12-Core Processor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- I originally went for Ryzen 7 3700X, which has 8 cores and planned to spend more money on the memory (getting 128GiB). However, it seems that --&gt;
&lt;!-- buying more cores in CPU will be better.  --&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU Cooler: &lt;a href="https://amzn.to/3dt2fv8"&gt;Noctua NH-D15 chromax.black 82.52 CFM CPU Cooler&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Motherboard: &lt;a href="https://amzn.to/3JTRVbM"&gt;MSI MPG B550 GAMING EDGE WIFI ATX AM4&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- According to &lt;a href="https://www.msi.com/Motherboard/B550-A-PRO/Specification"&gt;official specification&lt;/a&gt;, the board supports two M.2 with one of them supports  --&gt;
&lt;!-- PCIe 4.0. The board has two PCIe x16 but one of them will be disabled when a specific M.2 is inserted with SSD. I think one PCIe x16 should be good enough, --&gt;
&lt;!-- which is for graphics card. Given the price of the board, I'm fine with this choice. Note that this board has built-in Wireless card, which needs to check --&gt;
&lt;!-- whether it is good (i.e., latest wireless card) --&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Memory: &lt;a href="https://amzn.to/3JU3DD5"&gt;Crucial Ballistix 64 GB (2 x 32 GB) DDR4-3600 CL16 Memory&lt;/a&gt;&lt;/p&gt;
&lt;!-- Brand matters here. I consult with a friend and he speaks highly of Crucial memory sticks. --&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Storage: &lt;a href="https://amzn.to/3bTBFuN"&gt;SK hynix Gold P31 1 TB M.2-2280 NVME Solid State Drive&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- Brand seems to matter the most here. &lt;a href="https://pcpartpicker.com/product/QQrmP6/western-digital-sn750-1-tb-m2-2280-solid-state-drive-wds100t3x0c"&gt;Western Digital&lt;/a&gt;,  --&gt;
&lt;!-- Samsung, and SK hynix are regarded highly due to their in-house memory production.  --&gt;
&lt;!-- Given the price of memory sticks supporting PCIe 4.0 and the negligible performance difference between PCIe 3.0 and PCIe 4.0, --&gt;
&lt;!-- PCIe.3.0 memory sticks should be good enough. --&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Case: &lt;a href="https://amzn.to/3bZy3Hz"&gt;Fractal Design Meshify C ATX Mid Tower Case&lt;/a&gt;&lt;/p&gt;
&lt;!-- This case has a quite nice airflow. The downside is limited spaces for HDDs, which I don't think I'll need them anyway. --&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Power Supply: &lt;a href="https://amzn.to/3bQQyho"&gt;Super Flower Leadex III Gold 850 W 80+ Gold Certified Fully Modular ATX Power Supply&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- &lt;a href="https://www.newegg.com/seasonic-focus-plus-650-gold-ssr-650fx-650w/p/N82E16817151186"&gt;Seasonic&lt;/a&gt; and Super Flower --&gt;
&lt;!-- focus on PSU according to the same friend. --&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Graphics Card: A friend gives me a used graphics card&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- ## Troubleshooting  --&gt;
&lt;!-- - CPU cooler, AMD stock backplate --&gt;
&lt;!-- - Chasis fans connection: sys_fan, pump_fan --&gt;
&lt;!-- - No audio --&gt;
&lt;!-- - GPU connection: 6-pin, VGA cables from PSU --&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://artofpc.com/what-are-the-parts-in-a-computer/"&gt;What Are the Parts in a Computer? Basic Components Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://artofpc.com/how-to-pick-your-pc-parts/"&gt;How to Pick your PC Parts: Component selection basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://artofpc.com/motherboard-connectors-and-components/"&gt;Motherboard Anatomy: Connections and Components of the PC Motherboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pcmag.com/news/buying-a-solid-state-drive-20-terms-you-need-to-know"&gt;Buying a Solid-State Drive: 20 Terms You Need to Know&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pcmag.com/picks/the-best-pci-express-nvme-solid-state-drives-ssds"&gt;The Best PCI Express NVMe Solid State Drives (SSDs) for 2021&lt;/a&gt; despite 
  its title, the article contains many points you need to consider when picking a SSD and slots support from motherboard.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.coolblue.be/en/advice/what-should-i-keep-in-mind-m2-ssd.html"&gt;What should I keep in mind when buying a M.2 SSD?&lt;/a&gt; explains B-key and M-key difference 
  and M.2 slot specification&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pcguide101.com/motherboard/what-are-pcie-x1-slots-used-for/"&gt;What are PCIe x1 Slots Used For?&lt;/a&gt; introduces general concepts on PCIe slots and lanes
  with an answer to PCIe x1 slot.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.easypc.io/cpu/"&gt;Exactly How to Choose a CPU: Complete Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appuals.com/how-to-check-pcie-m-2-nvme-ssds-compatibility-with-your-pc/"&gt;How to Check PCIe M.2 NVMe SSDs Compatibility with your PC or Motherboard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;For M.2 storage drives or WiFi/Bluetooth expansion cards. Learn more &lt;a href="https://searchstorage.techtarget.com/definition/M2-SSD"&gt;here&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Corresponds to Motherboard Power Connector (i.e., ATX Power Connector) on the motherboard. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2021"></category><category term="hardware"></category></entry><entry><title>"Synthesizing Data Structure Transformations from Input-Output Examples"</title><link href="https://zhu45.org/posts/2021/Jan/28/synthesizing-data-structure-transformations-from-input-output-examples/" rel="alternate"></link><published>2021-01-28T04:20:00+08:00</published><updated>2021-01-28T04:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2021-01-28:/posts/2021/Jan/28/synthesizing-data-structure-transformations-from-input-output-examples/</id><summary type="html">&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;The paper presents a method to synthesize functional programs that transform recursive data
structures (e.g., lists, trees)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Examples: see Figure 6 (e.g., &lt;tt class="docutils literal"&gt;join&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;cprod&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;essentially shows how one can orchestrate a list of operators to generate the desired program&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Three techniques&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;type-aware inductive generalization&lt;ul&gt;
&lt;li&gt;purpose: create hypotheses that …&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;The paper presents a method to synthesize functional programs that transform recursive data
structures (e.g., lists, trees)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Examples: see Figure 6 (e.g., &lt;tt class="docutils literal"&gt;join&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;cprod&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;essentially shows how one can orchestrate a list of operators to generate the desired program&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Three techniques&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;type-aware inductive generalization&lt;ul&gt;
&lt;li&gt;purpose: create hypotheses that represent some or all properties of the target program&lt;ul&gt;
&lt;li&gt;can be open -&amp;gt; contains "holes"&lt;/li&gt;
&lt;li&gt;can be closed -&amp;gt; if is consistent with examples, this is the program&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;input: inferred types from examples&lt;ul&gt;
&lt;li&gt;use types -&amp;gt; prune the search space&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;output: a stream of hypotheses (closed and open) that match types&lt;/li&gt;
&lt;li&gt;how:&lt;ul&gt;
&lt;li&gt;For open hypothesis, application of a higher-order combinator (Figure 3) to set of (known or unknown) arguments
(use inferred types of examples to guide the selection of combinator)&lt;/li&gt;
&lt;li&gt;For close hypothesis, recursive procedure like enumerate search&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;deduction&lt;ul&gt;
&lt;li&gt;purpose: solve unknown functions in hypotheses&lt;/li&gt;
&lt;li&gt;Two techniques:&lt;ul&gt;
&lt;li&gt;Refutation: use counter-example to reject hypotheses&lt;/li&gt;
&lt;li&gt;Example inference: uses properties of combinators to infer new examples on unknown functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;best-first enumerate search&lt;ul&gt;
&lt;li&gt;weighted BFS idea -&amp;gt; use priority queue&lt;/li&gt;
&lt;li&gt;weight created from cost model: simple is better (avoid degenerate case: prog packed with if-blocks)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Main algorithm&lt;/p&gt;
&lt;img alt="Synthesis procedure" class="img-responsive" src="/images/feser2015synthesizing/fig2.png"/&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;a priority queue &lt;span class="math"&gt;\(Q\)&lt;/span&gt; of subtasks &lt;span class="math"&gt;\((e, f, \mathcal{E})\)&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(e\)&lt;/span&gt;: a hypothesis&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(f\)&lt;/span&gt;: a hole in hypothesis&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(\mathcal{E}\)&lt;/span&gt;:  a set of examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;pop the head of queue and obtain a subtask to work on&lt;ul&gt;
&lt;li&gt;if &lt;span class="math"&gt;\(e\)&lt;/span&gt; is closed, checking agains input examples&lt;ul&gt;
&lt;li&gt;ok -&amp;gt; got a solution; discard otherwise&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;if &lt;span class="math"&gt;\(e\)&lt;/span&gt; is open&lt;ul&gt;
&lt;li&gt;synthesize &lt;span class="math"&gt;\(f\)&lt;/span&gt; in &lt;span class="math"&gt;\(e\)&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;infer type of &lt;span class="math"&gt;\(f\)&lt;/span&gt; from &lt;span class="math"&gt;\(\mathcal{E}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;use inductive generalization to create a stream of hypotheses &lt;span class="math"&gt;\(H\)&lt;/span&gt; for &lt;span class="math"&gt;\(f\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;replace &lt;span class="math"&gt;\(f\)&lt;/span&gt; with each &lt;span class="math"&gt;\(h \in H\)&lt;/span&gt; to obtain a set of new hypotheses. Say one of them is &lt;span class="math"&gt;\(e'\)&lt;/span&gt;&lt;ul&gt;
&lt;li&gt;if &lt;span class="math"&gt;\(e'\)&lt;/span&gt; is closed -&amp;gt; put &lt;span class="math"&gt;\((e', \perp, \emptyset)\)&lt;/span&gt; as a subtask to queue&lt;/li&gt;
&lt;li&gt;if &lt;span class="math"&gt;\(e'\)&lt;/span&gt; is open&lt;ul&gt;
&lt;li&gt;new subtask for each hole &lt;span class="math"&gt;\(f^*\)&lt;/span&gt; in &lt;span class="math"&gt;\(e'\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;uses deduction on &lt;span class="math"&gt;\(f^*\)&lt;/span&gt; to create new examples &lt;span class="math"&gt;\(\mathcal{E^*}\)&lt;/span&gt; or refute&lt;/li&gt;
&lt;li&gt;add &lt;span class="math"&gt;\((e', f^*, \mathcal{E^*})\)&lt;/span&gt; as a subtask if not rejected&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2021"></category><category term="papers"></category><category term="program synthesis"></category></entry><entry><title>Graph Data Models</title><link href="https://zhu45.org/posts/2021/Jan/14/graph-data-models/" rel="alternate"></link><published>2021-01-14T23:20:00+08:00</published><updated>2021-01-14T23:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2021-01-14:/posts/2021/Jan/14/graph-data-models/</id><summary type="html">&lt;p&gt;It has been a very long time since my last post. As you might know, I left AWS and started to work on my PhD.
Research takes almost all my time. I have written a lot for my research, which consumes all my blogging energy.
However, I decided to try …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It has been a very long time since my last post. As you might know, I left AWS and started to work on my PhD.
Research takes almost all my time. I have written a lot for my research, which consumes all my blogging energy.
However, I decided to try out a new format on blogging - blogging topics around my research via short videos.
Below is my first one. Please let me know what you think in the comment section below.&lt;/p&gt;
&lt;div class="youtube youtube-16x9"&gt;&lt;iframe allowfullscreen="" frameborder="0" seamless="" src="https://www.youtube.com/embed/dK0eFR9gSWA"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Here is a short summary on the content:&lt;/p&gt;
&lt;p&gt;In the video above, I talked about two commonly-seen data models used by graph databases&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Edge-labelled graph (basis of &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Triplestore"&gt;Triplestore&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Property graph (used by Neo4j, TigerGraph, etc)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, I discussed the difference between graph models and the relational model by showing how
we can model the same piece of data from &lt;a class="reference external" href="https://en.wikipedia.org/wiki/The_Office_(American_TV_series"&gt;The Office&lt;/a&gt;
under different models. In addition, I listed the advantages that graph models can offer from user perspective.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;For Chinese viewers, you can find the video on &lt;a class="reference external" href="https://www.bilibili.com/video/BV1sT4y1K7Cr"&gt;BiliBili&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</content><category term="2021"></category><category term="database"></category></entry><entry><title>Status Update</title><link href="https://zhu45.org/posts/2020/Mar/04/status-update/" rel="alternate"></link><published>2020-03-04T12:20:00+08:00</published><updated>2020-03-04T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2020-03-04:/posts/2020/Mar/04/status-update/</id><summary type="html">&lt;p&gt;As you all probably have noticed, I have been quiet since October last
year. Here is a status update on my side: September last year, I was
laid off due to the strategic change of my last employer and I was
busy with job hunting.  Luckily, I’m able to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As you all probably have noticed, I have been quiet since October last
year. Here is a status update on my side: September last year, I was
laid off due to the strategic change of my last employer and I was
busy with job hunting.  Luckily, I’m able to join AWS in January
this year to work on a &lt;a href="https://aws.amazon.com/timestream/"&gt;new database service&lt;/a&gt; 
that will be launched later this year. In my spare time, I’m working on a project that is
not readily available to the public and that steals lots of blogging
time. However, the good news is that I’m still writing: I have written
a set of notes that will be made public once the time is right. So,
stay tuned!&lt;/p&gt;</content><category term="2020"></category><category term="meta"></category></entry><entry><title>Semaphore</title><link href="https://zhu45.org/posts/2019/Oct/20/semaphore/" rel="alternate"></link><published>2019-10-20T17:10:00+08:00</published><updated>2019-10-20T17:10:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-10-20:/posts/2019/Oct/20/semaphore/</id><summary type="html">&lt;p&gt;Concurrency is a big topic that I’m planning to write about more for the upcoming days. In this post, I’ll cover
the concept “semaphore”, a very important concept when we talk about synchronization. I’ll walk through concept and 
offer an implementation of semaphore in C++ with a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Concurrency is a big topic that I’m planning to write about more for the upcoming days. In this post, I’ll cover
the concept “semaphore”, a very important concept when we talk about synchronization. I’ll walk through concept and 
offer an implementation of semaphore in C++ with a working example. 
Lastly, I’ll apply &lt;a href="https://tour.golang.org/concurrency/2"&gt;golang’s channel concept&lt;/a&gt; to help us better understand semaphore.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#why-semaphore"&gt;Why Semaphore?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#concept-and-implementation"&gt;Concept and Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#example"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#glimpse-from-golang"&gt;Glimpse from Golang&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#summary"&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="why-semaphore"&gt;Why Semaphore?&lt;/h2&gt;
&lt;p&gt;Lock (e.g., mutex), condition variable, and semaphore are three tightly-coupled concepts that everyone will learn about
in their undergraduate OS course. &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-sema.pdf"&gt;Some textbook&lt;/a&gt; presents those concepts
in the ordering shown above and talks about the missions that each concurrency primitive can achieve. In practice, however, I always find it is challenging to make choice when multiple options present for handling a specific usage scenario. The following
is some rules of thumb I like to use when work with those concepts in practice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Semaphore replaces “everything”: I can use semaphore to work both as lock to protect shared data across multiple threads (i.e., threads can access data but only one at a time) and as condition variable &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; to order the events (e.g., ordering the access of shared data; ordering the execution of threads).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mutex is just a easeir tool to use under lock scenario. In other words, we can use semaphore as the lock but implements semaphore itself requires more LOC than mutex (i.e., if we only need lock, use mutex).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use condition variable and mutex to implement semaphore and use semaphore as the abstraction for the rest of code. Certainly, one can say using condition variable + mutex for threads ordering but essentially, he is using semaphore (by constructing it with condition variable + mutex first) without explicitly stating it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;I find how we understand those three concepts implicitly ill shaped by C, which is the default language used in undergraduate OS course. For example, C POSIX has a nice “&lt;a href="https://pubs.opengroup.org/onlinepubs/7908799/xsh/semaphore.h.html"&gt;semaphore.h&lt;/a&gt;” inteface that allows user to use semaphore &lt;a href="http://www.csc.villanova.edu/~mdamian/threads/posixsem.html"&gt;directly&lt;/a&gt;. Such existence of interface makes one to direct use &lt;code&gt;semaphore.h&lt;/code&gt; for using semaphore and &lt;a href="https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html"&gt;pthread.h&lt;/a&gt; for condition variable and mutex. The consequence of such usage is that one can easily think that if they are using condition variable + mutex, they are using condition variable instead of semaphore on conceptual level. This is wrong! What they are really doing is to first construct semaphore using condition variable + mutex and then using semaphore to achieve the desired goal. The only difference between their usage and using semaphore directly is the lack of semaphore as an object abstraction. From this angle, I think C++ with LLVM compiler on Mac does a much better job by &lt;a href="https://stackoverflow.com/questions/27736618/why-are-sem-init-sem-getvalue-sem-destroy-deprecated-on-mac-os-x-and-w"&gt;deprecating POSIX semaphore.h C library&lt;/a&gt;. This forces me to use standard &lt;a href="https://en.cppreference.com/w/cpp/thread/mutex"&gt;mutex&lt;/a&gt; and &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable"&gt;condition variable&lt;/a&gt; to implement semaphore first before using it (also makes the code much more portable), which helps me to discover this sublte relationship among three concepts that is masked out in OS and C world. However, I’m not stating that all the condition variable + mutex usage will be equivalent to semaphore but semaphore can achieve the same purpose as condition variable with cleaner encapsulation.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Hopefully, by now, I can convince you why we need semaphore: it is such a indispensable tool in the pocket when we want to deal with commonly-seen concurrency situation: used as the lock to protect shared variable; used as ordering mechanism to facilitate threads execution order and concurrent event ordering.&lt;/p&gt;
&lt;h2 id="concept-and-implementation"&gt;Concept and Implementation&lt;/h2&gt;
&lt;p&gt;Before we jump into semaphore, let’s revisit mutex and condition variable concepts first because we will leverage those two concepts in our C++ implementation. Mutex is used to allow many threads to acess the same variable but only do so one at a time. It is a
useful tool to avoid data race: a situation where two threads acess the same variable concurrently and at least one of the access is a write (e.g., Alice deposits $200 into bank with initial balance is 0; Bob deposits $100 to the same account and the final balance can be $200 &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;). Whenever a thread wants to modify a shared variable, it needs to acquire mutex first and release the mutex after the modification. Condition variable is used to put one thread to sleep until the condition the thread is waiting for comes true. A condition variable is an explicit queue that threads can put themselves on when some state of execution (i.e., some condition) is not as desired (by &lt;strong&gt;waiting&lt;/strong&gt; on the condition); some other thread, when it changes said state, can then wake one (or more) of those waiting threads and thus allow them to continue (by &lt;strong&gt;signaling&lt;/strong&gt; on the condition).&lt;/p&gt;
&lt;p&gt;A semaphore is an object with an integer value that we can manipulate with an increment-value method (let’s denote such method as &lt;code&gt;post()&lt;/code&gt;) and a decrement-value method (let’s denote such method as &lt;code&gt;wait()&lt;/code&gt;). Then, the semantics of semaphore is defined by
the functionality of &lt;code&gt;post()&lt;/code&gt; and &lt;code&gt;wait()&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;In the following, when we talk about the value of semaphore, we really mean the integer value contained inside semaphore.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// increment the semaphore value by one&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// if there are one or more threads waiting on the semaphore, wake one&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// decrement the semaphore value by one&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// wait if the resulting semaphore value is negative&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is the pseudo code for the semaphore implementation:&lt;/p&gt;
&lt;p&gt;&lt;img alt="semaphore pseudo code" class="img-responsive" src="https://zhu45.org/images/semaphore.png"/&gt;&lt;/p&gt;
&lt;p&gt;Now, let’s implement semaphore in C++ with the semantics stated above.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Semaphore&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;condition_variable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// only one thread can call this; by default, we construct a binary semaphore&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;explicit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Semaphore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;avail_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avail_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unique_lock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;unique_lock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify_one&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since we modify the integer value of semaphore (&lt;code&gt;avail&lt;/code&gt;) that can be updated by multiple threads concurrently, 
we need to use mutex (&lt;code&gt;m&lt;/code&gt;) to ensure only one thread doing the update. 
In addition, since threads need to wake up or wait depending on situation, we need to use condition variable (&lt;code&gt;cv&lt;/code&gt;).
The implementation itself follows some standard practice when working with condition variable.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Here, we describes the procedure in C++ context; but steps generally applied in other languages. Also, the standard practice
normally done by the thread. However, since the thread simply calls &lt;code&gt;post()&lt;/code&gt; and &lt;code&gt;wait()&lt;/code&gt;, the practice is now presented in
the &lt;code&gt;post()&lt;/code&gt; and &lt;code&gt;wait()&lt;/code&gt; implementation.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;For thread calling &lt;code&gt;post()&lt;/code&gt; (i.e., the thread that intends to modify the value of semaphore), &lt;code&gt;post()&lt;/code&gt; has to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;acquire a &lt;a href="https://en.cppreference.com/w/cpp/thread/mutex"&gt;std::mutex&lt;/a&gt; (usually via &lt;a href="https://en.cppreference.com/w/cpp/thread/lock_guard"&gt;std::lock_guard&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;perform the modification while the lock is held (e.g., &lt;code&gt;avail++&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;execute &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable/notify_one"&gt;notify_one&lt;/a&gt; or &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable/notify_all"&gt;notify_all&lt;/a&gt; on the &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable"&gt;std::condition_variable&lt;/a&gt; &lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For thread calling &lt;code&gt;wait()&lt;/code&gt; (e.g., any threads that intends to wait on the condition variable in semaphore), &lt;code&gt;wait()&lt;/code&gt; has to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;acquire a &lt;a href="https://en.cppreference.com/w/cpp/thread/unique_lock"&gt;std::unique_lock&lt;std::mutex&gt;&lt;/std::mutex&gt;&lt;/a&gt; on the same mutex as used to protect the shared variable&lt;/li&gt;
&lt;li&gt;execute &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable/wait"&gt;wait&lt;/a&gt; &lt;sup id="fnref:6"&gt;&lt;a class="footnote-ref" href="#fn:6"&gt;4&lt;/a&gt;&lt;/sup&gt;, &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable/wait_for"&gt;wait_for&lt;/a&gt;, or &lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable/wait_until"&gt;wait_until&lt;/a&gt;. The wait operations atomically release the mutex and suspend the execution of the thread.&lt;/li&gt;
&lt;li&gt;when the condition variable is notified, a timeout expires, or a &lt;a href="https://en.wikipedia.org/wiki/Spurious_wakeup"&gt;spurious wakeup&lt;/a&gt; occurs, the thread is awakened, and the mutex is atomically reacquired. The thread should then check the condition and resume waiting if the wake up was spurious &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;5&lt;/a&gt;&lt;/sup&gt;. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One might probably notice, there is no explicitly unlock or using &lt;code&gt;while&lt;/code&gt; to check for the wait condition (&lt;code&gt;avail &amp;gt; 0&lt;/code&gt;) inside the implementation. Actually, those operations happen but are hidden by the C++ library implementation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We acquire mutex lock via &lt;a href="http://www.cplusplus.com/reference/mutex/unique_lock/"&gt;std::unique_lock&lt;/a&gt; and since &lt;code&gt;std::unqiue_lock&lt;/code&gt; guarantees an unlocked
status on &lt;code&gt;mutex&lt;/code&gt; on destruction and &lt;code&gt;std::unqiue_lock&lt;/code&gt; destructor will be automatically invoked when the &lt;code&gt;wait()&lt;/code&gt; or &lt;code&gt;post()&lt;/code&gt; exits, &lt;code&gt;mutex&lt;/code&gt; will be unlocked on function exit.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://en.cppreference.com/w/cpp/thread/condition_variable/wait"&gt;std::condition_variable::wait&lt;/a&gt; has the function signature &lt;code&gt;template&amp;lt; class Predicate &amp;gt; void wait( std::unique_lock&amp;lt;std::mutex&amp;gt;&amp;amp; lock, Predicate pred );&lt;/code&gt; (e.g., &lt;code&gt;cv.wait()&lt;/code&gt;) and inside the function, it does &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thus, &lt;code&gt;cv.wait(lk, [this] { return avail &amp;gt; 0; });&lt;/code&gt; can be expanded as &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avail&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;An intuitve read of &lt;code&gt;cv.wait(lk, [this] { return avail &amp;gt; 0; });&lt;/code&gt; is the thread will wait until &lt;code&gt;avail &amp;gt; 0&lt;/code&gt;, the condition contained in the lambda function argument. This can probably saves some brain power to do the expansion shown above. &lt;/p&gt;
&lt;p&gt;To make the implementation easier to understand, I borrow the reference implementation in C from &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-sema.pdf"&gt;OSTEP&lt;/a&gt;. Hopefully, it will make the C++ implementation clearer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;__Zem_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;pthread_cond_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;pthread_mutex_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Zem_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// only one thread can call this&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Zem_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Zem_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Cond_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Mutex_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Zem_wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Zem_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Cond_wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Zem_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Zem_t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Cond_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="example"&gt;Example&lt;/h2&gt;
&lt;p&gt;As one can probably see, semaphore doesn’t offer much freedom when come to how much we can customize it. The only thing that can be set by the user
is the initial integer value of the semaphore (e.g., &lt;code&gt;avail&lt;/code&gt;). In fact, that’s the beauty of the semaphore: we can achieve various purposes with semaphore by initalizing it with different values. For exmaple, we can intialize the semaphore with value &lt;code&gt;1&lt;/code&gt; to make the semaphore work like a lock (such semaphore is called &lt;strong&gt;binary semaphore&lt;/strong&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// deposit called by multiple threads to update balance&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;lk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is an intuitive description to understand semaphore based on this deposit example: Suppose there are five people want to withdraw money
from the bank. Semaphore works like a key hanging on the bank door. Since the semaphore value is intialized with one, there is only one key hang on the door. The first person arrives at the bank is able to grab the key, open the door, and withdraw money. The rest four people have to wait in line for the key. Once the first person finishes the withdrawing, he puts the key back to the door and pat the next person’s shoulder and tells her the key is available and she can go in. Now, the second person checks the key is indeed hang on the door and now she can grab it to withdraw. The whole process repeats for the rest three person waiting in the line. This describes the five threads with one semaphore situation. &lt;/p&gt;
&lt;p&gt;We can also set semaphore value properly to order the threads execution. Consider the &lt;a href="https://leetcode.com/problems/print-in-order/"&gt;Leetcode Problem: 1114. Print In Order&lt;/a&gt; where we pass the same object &lt;code&gt;Foo&lt;/code&gt; into three threads and let them calling appropriate print methods to print “first”, “second”, and “third” in such ordering without restricting which thread is assigned to print which word. For detailed example, see the problem description. The following implementation shows how we can use semaphore implementation shown above to achieve such ordering purpose: always print “first”, “second”, and “third” in order:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;firstJobDone&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secondJobDone&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;firstJobDone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;secondJobDone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;printFirst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printFirst&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;firstJobDone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;printSecond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;firstJobDone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printSecond&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;secondJobDone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;third&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;printThird&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;secondJobDone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printThird&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Both &lt;code&gt;firstJobDone&lt;/code&gt; and &lt;code&gt;secondJobDone&lt;/code&gt; have semaphore value of &lt;code&gt;0&lt;/code&gt; when the &lt;code&gt;Foo&lt;/code&gt; class is constructed. 
Both &lt;code&gt;second()&lt;/code&gt; and &lt;code&gt;third()&lt;/code&gt; will call &lt;code&gt;wait()&lt;/code&gt; method on respective semaphore; unless &lt;code&gt;post()&lt;/code&gt; is called before &lt;code&gt;wait()&lt;/code&gt;, 
the value of semaphore will be 0, which will put threads calling &lt;code&gt;second()&lt;/code&gt; and &lt;code&gt;third()&lt;/code&gt; pause waiting on respective semaphore. Since &lt;code&gt;first()&lt;/code&gt; doesn’t call &lt;code&gt;wait()&lt;/code&gt; initially, &lt;code&gt;first()&lt;/code&gt; will be executed first. Then, &lt;code&gt;firstJobDone.post()&lt;/code&gt; will be called, which will bring &lt;code&gt;fristJobDone&lt;/code&gt; semaphore value to 1 and wake up the thread that wait on the semaphore: in this case, it’s the thread calling &lt;code&gt;second()&lt;/code&gt;. Since &lt;code&gt;secondJobDone&lt;/code&gt; semaphore value is still 0, thread calling &lt;code&gt;third()&lt;/code&gt; will continue to pause until thread with &lt;code&gt;second()&lt;/code&gt; done the work and increment the semaphore value. The complete implementation with test can be seen &lt;a href="https://github.com/xxks-kkk/shuati/blob/master/leetcode/1114-PrintInOrder/printInOrder.cc"&gt;here&lt;/a&gt;. Note that semaphore implementation used is abstracted in &lt;a href="https://github.com/xxks-kkk/shuati/blob/master/leetcode/cppinclude/mysemaphore.h"&gt;mysemaphore.h&lt;/a&gt; with implementation &lt;a href="https://github.com/xxks-kkk/shuati/blob/master/leetcode/cppinclude/mysemaphore.cc"&gt;here&lt;/a&gt;. Note that for this specific question, we initialize semaphores in the &lt;code&gt;Foo&lt;/code&gt; class. This is ok in this situation as there will be only one &lt;code&gt;Foo&lt;/code&gt; object exists. However, a more common case is to intialize semaphores globally.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Probably one may have noticed that the semantics of semaphore implementation has been slightly different than the
semantics of &lt;code&gt;wait()&lt;/code&gt; and &lt;code&gt;post()&lt;/code&gt; we defined above with the pseudo code comment. In fact, semaphore intially has
the invariant that: the value of the semaphore, when negative, is equal to the number of waiting threads &lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;6&lt;/a&gt;&lt;/sup&gt;. We use
invariant in the semantics definition instead of the actual implementation is to help remember semaphore functionality.
We certainly can modify the implementation to make it follow the invariant: we switch type of &lt;code&gt;avail&lt;/code&gt; from &lt;code&gt;size_t&lt;/code&gt;
to &lt;code&gt;int&lt;/code&gt; and change the wait condition from &lt;code&gt;avail &amp;gt; 0&lt;/code&gt; to &lt;code&gt;avail &amp;gt;= 0&lt;/code&gt;. The complete modified implementation can
be seen &lt;a href="https://github.com/xxks-kkk/shuati/pull/158"&gt;here&lt;/a&gt;. Note that to use this version of implementation in the 
“print in order” example above, we need to intialize both semaphores to &lt;code&gt;-1&lt;/code&gt; instead of &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="glimpse-from-golang"&gt;Glimpse from Golang&lt;/h2&gt;
&lt;p&gt;Recently, I learned about Golang for the work. The idea of using channel, the concept based on &lt;a href="https://en.wikipedia.org/wiki/Communicating_sequential_processes"&gt;communicating sequential process (CSP)&lt;/a&gt;, as the fundamental concurrency primitive really opens my mind (I’ve seen the idea in Python and Rust but Golang abuses the concept heavily). Such novel construction naturally brings new angle to re-examine the old concept: semaphore. The following examples are taken from &lt;a href="https://www.goodreads.com/book/show/25080953-the-go-programming-language"&gt;The Go Programming Language&lt;/a&gt; with page number 241, 250, and 262.&lt;/p&gt;
&lt;p&gt;The purpose of semaphore can be seen from limit parallelism: for example, no more than 20 concurrent calls to open a file. From
the golang world, we can use a buffered channel of capacity &lt;span class="math"&gt;\(n\)&lt;/span&gt; to construct the semaphore (or &lt;em&gt;counting semaphore&lt;/em&gt; if we want to be specific). Recall that a buffered channel has a queue of elements with the maximum queue size &lt;span class="math"&gt;\(n\)&lt;/span&gt; (i.e., capacity). A send operation on a buffered channel inserts an element at the back of the queue, and a receive operation removes an element from the front. Then the goroutine is blocked under the following conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If the channel is full, the goroutine with send operation will be blocked until space is available in the queue due to a receive by another goroutine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the channel is empty, the goroutine with receiver operation is blocked until a value is sent to the queue by another goroutine.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, conceptually, to implement semaphore, each of the &lt;span class="math"&gt;\(n\)&lt;/span&gt; vacant slots in the channel buffer (i.e., queue) represents a token
entitling the holder to proceed. Token is acquired by sending a value to the channel and is released by receiving a value 
from the channel. Receiving a value creates a new vacant slot that potentially allows other goroutine to send the value (i.e., acquire token). As one can probably see, with this setting, we can allow at most &lt;span class="math"&gt;\(n\)&lt;/span&gt; sends without an intervening receive.&lt;/p&gt;
&lt;p&gt;Implement semaphore in this way is surprisingly simple: all we need is a buffere channel and perform send or receive appropriately. The book provides an example of crawling the web (the book is from Google engineers; no wonder):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// tokens is a counting semaphore used to&lt;/span&gt;
&lt;span class="c1"&gt;// enforce a limit of 20 concurrent requests.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;chan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;crawl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// acquire a token&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;links&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// release the token&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we compare this Go’s implementation with our C++ one, we can see that &lt;code&gt;tokens &amp;lt;- struct{}{}&lt;/code&gt; works like &lt;code&gt;wait()&lt;/code&gt;: if we 
cannot send value to the channel, we wait until the channel has some vacant spot. &lt;code&gt;&amp;lt;-tokens&lt;/code&gt; works like &lt;code&gt;post()&lt;/code&gt;: we’re done and thus release token so that another goroutine can do the work. To generalize this implementation, we normally can:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// 20 is the intialized semaphore value&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;chan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;some_work&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// acquire token&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;defer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// release token&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// do the work ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To see how semaphore work as a lock (mutex) in Go, we can revisit previous concurrent balance update situation and make
both deposit and check the balance concurrent-safe:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;chan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// a binary semaphore guarding balance&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// acquire token&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// release token&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Balance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// acquire token&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="nx"&gt;semaphore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// release token&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;p&gt;Semaphore is a really powerful concurrency construct that can work like a lock, perform ordering, and limit parallelism. 
I always like to semaphore first and use it exculsively without scratching the head to write sppecific condition variable + mutex
combo for each kind of situation. Certainly, there will be case using conditon variable + mutex is more straightforward but I find it is very rare.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The similarity of semaphore and condition variable is suggested by the origin of condition variable idea: Dijkstra’s use of “&lt;a href="http://www.cs.utexas.edu/users/EWD/ewd01xx/EWD123.PDF"&gt;private semaphore&lt;/a&gt;”. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Think about why this can happen. If it is not clear, see &lt;a href="https://www.goodreads.com/book/show/25080953-the-go-programming-language"&gt;The Go Programming Language book p.259&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;“Always hold the lock while signaling” is one important tip for concurrency correctness mentioned in &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf"&gt;OSTEP&lt;/a&gt;. There is 4th step that release lock is omitted here because it is automatically taken 
care of by the destructor of &lt;code&gt;std::lock_guard&lt;/code&gt;. &lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;Inside &lt;code&gt;condition_variable::wait&lt;/code&gt;, unlocking the lock, blocking the current executing thread, and adding it to the list of threads waiting on &lt;code&gt;*this&lt;/code&gt; are executed atomically. &lt;a class="footnote-backref" href="#fnref:6" title="Jump back to footnote 4 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;That’s why we always use &lt;code&gt;while&lt;/code&gt; instead of &lt;code&gt;if&lt;/code&gt; when deciding whether to wait on the condition. In classroom, we normally learned the practice from the difference between Mesa semantics and Hoare semantics. See &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf"&gt;OSTEP&lt;/a&gt; for more details. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 5 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;The invariant is stated in one of &lt;a href="https://klevas.mif.vu.lt/~liutauras/books/Dijkstra%20-%20The%20structure%20of%20the%20THE%20multiprogramming%20system.pdf"&gt;Dijkstra’s papers&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 6 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2019"></category><category term="cpp"></category><category term="golang"></category><category term="concurrency"></category></entry><entry><title>Secure Connection with MariaDB: A Conceptual Approach</title><link href="https://zhu45.org/posts/2019/Sep/14/secure-connection-with-mariadb-a-conceptual-approach/" rel="alternate"></link><published>2019-09-14T23:20:00+08:00</published><updated>2019-09-14T23:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-09-14:/posts/2019/Sep/14/secure-connection-with-mariadb-a-conceptual-approach/</id><summary type="html">&lt;p&gt;In this post, I discuss how we can &lt;a href="https://www.cyberciti.biz/faq/how-to-setup-mariadb-ssl-and-secure-connections-from-clients/"&gt;have a secure connection with MariaDB&lt;/a&gt; by first understanding the computer science fundamentals behind the steps. Once we have built the concept model, the steps linked above are self-explanatory. In addition, this post applies the same concept to understand SSL ccertificate.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#concepts"&gt;Concepts …&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;In this post, I discuss how we can &lt;a href="https://www.cyberciti.biz/faq/how-to-setup-mariadb-ssl-and-secure-connections-from-clients/"&gt;have a secure connection with MariaDB&lt;/a&gt; by first understanding the computer science fundamentals behind the steps. Once we have built the concept model, the steps linked above are self-explanatory. In addition, this post applies the same concept to understand SSL ccertificate.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#concepts"&gt;Concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#examples"&gt;Examples&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#secure-connection-with-mariadb"&gt;Secure Connection with MariaDB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ssl-certificate"&gt;SSL Certificate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="concepts"&gt;Concepts&lt;/h2&gt;
&lt;p&gt;The key concept behind secure connection is &lt;a href="https://en.wikipedia.org/wiki/Certificate_authority#Overview"&gt;certificate&lt;/a&gt;, which relies on &lt;a href="https://en.wikipedia.org/wiki/Digital_signature"&gt;digital signature&lt;/a&gt;. The following picture shows the key idea of digital signature:&lt;/p&gt;
&lt;p&gt;&lt;img alt="digital signature" class="img-responsive" src="https://zhu45.org/images/digital_signature.png"/&gt;&lt;/p&gt;
&lt;p&gt;Suppose PayPal wants to ask the personal information from the end user. To allow user verify that PayPal indeed sends the message and such message (e.g., “Please enter your personal info”) is not modified, PayPal will use his private key to sign the message and distribute his public key to the end user. If the user can decode that message with PayPal’s public key, then end user can confirm two pieces of information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The sender is PayPal assuming the public key at hand truly belongs to PayPal (Authentication)&lt;/li&gt;
&lt;li&gt;The message is not modified in transit (Integrity)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, let’s examine further on Authentication. In the above scheme, the end user obtains public key from PayPal in order to decode the message that PayPal sends. This can be problematic: how do we know the public key the end user obtained is truly sent by PayPal? In other words, if a server owned by malicious attacker sends the public key to the user as if the server itself owned by PayPal, then the end user personal information will be in danager: of course the end user can use the public key from the malicious server to verify the authenticity and integrity of the message sent by malicious server; then the personal information sent by the user will be on the malicious server instead of on server owned by PayPal.&lt;/p&gt;
&lt;p&gt;To patch the loophole mentioned above, we rely on a trusted third party to help user to verify the publick key is truly owned by the claimed party (e.g., public key we obtained from “PayPal” is truly owned by PayPal). Such trusted third party is called &lt;a href="https://en.wikipedia.org/wiki/Certificate_authority"&gt;Certificate Authority (CA)&lt;/a&gt;. CA verifies the ownership of a public key by issuing digital certificates, which essentially a digital signature signed by CA on a specific message sent by the public key owner. The following picture demonstrates this concept:&lt;/p&gt;
&lt;p&gt;&lt;img alt="CA digital signature" class="img-responsive" src="https://zhu45.org/images/ca_digitial_certificates.png"/&gt;&lt;/p&gt;
&lt;p&gt;The most commonly seen example of digital certificate is the TLS/SSL server certificate, which is a certificate that server needs to present to the client
during initial connection setup when establishing a secure connection required by &lt;a href="https://en.wikipedia.org/wiki/Transport_Layer_Security"&gt;TLS/SSL Protocol&lt;/a&gt;. The following picture shows the digital certificates used by this site, which is certified by COMODO (&lt;a href="https://en.wikipedia.org/wiki/Certificate_authority#Providers"&gt;one of CA providers&lt;/a&gt;) and issued to Cloudflare, the domain name server provider:&lt;/p&gt;
&lt;p&gt;&lt;img alt="digital certificates shown by zhu45.org" class="img-responsive" src="https://zhu45.org/images/digitial_certificates_homepage.png"/&gt;&lt;/p&gt;
&lt;p&gt;A special message sent by the public key owner (e.g., PayPal) to obtain CA digital certificate is called &lt;a href="https://en.wikipedia.org/wiki/Certificate_signing_request"&gt;Certificate Signing Request (CSR)&lt;/a&gt;. For example, to create a private key (e.g., &lt;code&gt;server-key.pem&lt;/code&gt;) along with CSR  (e.g., &lt;code&gt;server-req.pem&lt;/code&gt;) on Mac, one can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;openssl&lt;span class="w"&gt; &lt;/span&gt;req&lt;span class="w"&gt; &lt;/span&gt;-newkey&lt;span class="w"&gt; &lt;/span&gt;rsa:2048&lt;span class="w"&gt; &lt;/span&gt;-days&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;365000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-nodes&lt;span class="w"&gt; &lt;/span&gt;-keyout&lt;span class="w"&gt; &lt;/span&gt;server-key.pem&lt;span class="w"&gt; &lt;/span&gt;-out&lt;span class="w"&gt; &lt;/span&gt;server-req.pem
Generating&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2048&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;bit&lt;span class="w"&gt; &lt;/span&gt;RSA&lt;span class="w"&gt; &lt;/span&gt;private&lt;span class="w"&gt; &lt;/span&gt;key
..............+++
.......................................+++
writing&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;private&lt;span class="w"&gt; &lt;/span&gt;key&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'server-key.pem'&lt;/span&gt;
-----
You&lt;span class="w"&gt; &lt;/span&gt;are&lt;span class="w"&gt; &lt;/span&gt;about&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;asked&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;enter&lt;span class="w"&gt; &lt;/span&gt;information&lt;span class="w"&gt; &lt;/span&gt;that&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;incorporated
into&lt;span class="w"&gt; &lt;/span&gt;your&lt;span class="w"&gt; &lt;/span&gt;certificate&lt;span class="w"&gt; &lt;/span&gt;request.
What&lt;span class="w"&gt; &lt;/span&gt;you&lt;span class="w"&gt; &lt;/span&gt;are&lt;span class="w"&gt; &lt;/span&gt;about&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;enter&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;what&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;called&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;Distinguished&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;DN.
There&lt;span class="w"&gt; &lt;/span&gt;are&lt;span class="w"&gt; &lt;/span&gt;quite&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;few&lt;span class="w"&gt; &lt;/span&gt;fields&lt;span class="w"&gt; &lt;/span&gt;but&lt;span class="w"&gt; &lt;/span&gt;you&lt;span class="w"&gt; &lt;/span&gt;can&lt;span class="w"&gt; &lt;/span&gt;leave&lt;span class="w"&gt; &lt;/span&gt;some&lt;span class="w"&gt; &lt;/span&gt;blank
For&lt;span class="w"&gt; &lt;/span&gt;some&lt;span class="w"&gt; &lt;/span&gt;fields&lt;span class="w"&gt; &lt;/span&gt;there&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;value,
If&lt;span class="w"&gt; &lt;/span&gt;you&lt;span class="w"&gt; &lt;/span&gt;enter&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;field&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;left&lt;span class="w"&gt; &lt;/span&gt;blank.
-----
Country&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;letter&lt;span class="w"&gt; &lt;/span&gt;code&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:
State&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;Province&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;full&lt;span class="w"&gt; &lt;/span&gt;name&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:
Locality&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;eg,&lt;span class="w"&gt; &lt;/span&gt;city&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:
Organization&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;eg,&lt;span class="w"&gt; &lt;/span&gt;company&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:
Organizational&lt;span class="w"&gt; &lt;/span&gt;Unit&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;eg,&lt;span class="w"&gt; &lt;/span&gt;section&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:
Common&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;eg,&lt;span class="w"&gt; &lt;/span&gt;fully&lt;span class="w"&gt; &lt;/span&gt;qualified&lt;span class="w"&gt; &lt;/span&gt;host&lt;span class="w"&gt; &lt;/span&gt;name&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Zeyuan&lt;span class="s1"&gt;'s laptop&lt;/span&gt;
&lt;span class="s1"&gt;Email Address []:&lt;/span&gt;

&lt;span class="s1"&gt;Please enter the following '&lt;/span&gt;extra&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;attributes
to&lt;span class="w"&gt; &lt;/span&gt;be&lt;span class="w"&gt; &lt;/span&gt;sent&lt;span class="w"&gt; &lt;/span&gt;with&lt;span class="w"&gt; &lt;/span&gt;your&lt;span class="w"&gt; &lt;/span&gt;certificate&lt;span class="w"&gt; &lt;/span&gt;request
A&lt;span class="w"&gt; &lt;/span&gt;challenge&lt;span class="w"&gt; &lt;/span&gt;password&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;At this stage, avid reader like you might notice that there can still exist potential loophole: how do we know the public key the user obtained from “CA” is truly owned by CA? Here, CA makes an exaception here: CA issues its own CA digital certificate by signing on its own using its own private key (such digital certificate owned by CA is called &lt;a href="https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc778623(v=ws.10)?redirectedfrom=MSDN"&gt;CA certificate&lt;/a&gt;). Then we rely on regulation and industry auditing to ensure CA providers can play as a trusted third party.&lt;/p&gt;
&lt;p&gt;One concept needs to clarify is that CA is not resources controlled by serveral public providers: large organizations usually have their own CAs as part of their own &lt;a href="https://en.wikipedia.org/wiki/Public_key_infrastructure"&gt;public key infrastructure&lt;/a&gt;. For example, if a company decides to build their own private cloud, they may have their own CAs to help with internal network traffic encryption. To show a concrete example, we can generate our own CA certificate like below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Generate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;openssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;genrsa&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pem&lt;/span&gt;
&lt;span class="nx"&gt;Generating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;RSA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;modulus&lt;/span&gt;
&lt;span class="o"&gt;........................+++&lt;/span&gt;
&lt;span class="o"&gt;........................................................................................................................+++&lt;/span&gt;
&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;65537&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x10001&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;signed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;certificate&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;openssl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;x509&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;365000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ca&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pem&lt;/span&gt;
&lt;span class="nx"&gt;You&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;about&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;asked&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;enter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;information&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;incorporated&lt;/span&gt;
&lt;span class="nx"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;certificate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;What&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;about&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;enter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;called&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Distinguished&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;There&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;quite&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;few&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;blank&lt;/span&gt;
&lt;span class="nx"&gt;For&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;there&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;enter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;blank&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;-----&lt;/span&gt;
&lt;span class="nx"&gt;Country&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;
&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Province&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;full&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;
&lt;span class="nx"&gt;Locality&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;
&lt;span class="nx"&gt;Organization&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;
&lt;span class="nx"&gt;Organizational&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Unit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;
&lt;span class="nx"&gt;Common&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fully&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;qualified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;&lt;span class="nx"&gt;Zeyuan&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;laptop&lt;/span&gt;
&lt;span class="nx"&gt;Email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Normally, in an organization setting (e.g., build an internal private cloud), several concepts emerge with CA certificate: &lt;a href="https://en.wikipedia.org/wiki/Root_certificate"&gt;root certificate&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Public_key_certificate#Types_of_certificate"&gt;intermediate certificate&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/Chain_of_trust"&gt;chain of trust&lt;/a&gt;. The following picture demonstrates this concept:&lt;/p&gt;
&lt;p&gt;&lt;img alt="chain of trust" class="img-responsive" src="https://zhu45.org/images/chain_of_trust.png"/&gt;&lt;/p&gt;
&lt;p&gt;As one can see in the picture, root CA certificate is issued by root CA itself, and such certificate is called “root certificate”. The reason for such naming reflects such CA is the root in the tree structure, which means a point of ultimate trust for a CA hierarchy. The CA in the middle of the picture holds “intermediate certificate”, which is a certificate signed by another intermediate CA or a root CA. Intermediate CA can sign CSR as if it is root CA. Requester (e.g., PayPal)’s certificate obtained via this way is secure because each CA in the CA hierarchy is validated by its ancestor, which can be traced back all the way to the root CA. Thus, requester’s certificate can be treated as if it is directly obtained from root CA, the ultimate trusted party.&lt;/p&gt;
&lt;p&gt;Take building private cloud as an example, one usage scenario of CA hierarchy is to eastablish secure connection between API server and database server. The following picture shows such organization:&lt;/p&gt;
&lt;p&gt;&lt;img alt="CA usage example" class="img-responsive" src="https://zhu45.org/images/ca_usage_example.png"/&gt;&lt;/p&gt;
&lt;p&gt;There are two things need to note in the picture: one is the dot line between CA and API server, which indicates they are optional. TLS/SSL protocol does not enforce the client (e.g., API server) to present certificate (i.e., one-way TLS). However, if the database is configured to enable two-way TLS (&lt;a href="https://mariadb.com/kb/en/library/securing-connections-for-client-and-server/#enabling-one-way-tls-for-mariadb-clients"&gt;MariaDB&lt;/a&gt;), then it is necessary for client to obtain certificate as well. The second is authentication and encryption is a separation of concern: for one-way TLS, we only care about encryption of API access to database and we can choose different method to perform authentication (e.g., user and password).&lt;/p&gt;
&lt;h2 id="examples"&gt;Examples&lt;/h2&gt;
&lt;h3 id="secure-connection-with-mariadb"&gt;Secure Connection with MariaDB&lt;/h3&gt;
&lt;p&gt;Now, with the concept model we build so far, we can easily understand &lt;a href="https://www.cyberciti.biz/faq/how-to-setup-mariadb-ssl-and-secure-connections-from-clients/"&gt;the listed step about setup secure connection with MariaDB&lt;/a&gt;, which have both CA and MariaDB sit on the same server and use two-way TLS for both authentication and encryption of database access.&lt;/p&gt;
&lt;h3 id="ssl-certificate"&gt;SSL Certificate&lt;/h3&gt;
&lt;p&gt;For security connection, web server needs to obtain SSL certificate by sending CSR to CA. In addition, the web server usually also installs intermediate certificate to establishes the credibility of SSL Certificate by tying it to CA’s root certificate. The following picture shows why this works:&lt;/p&gt;
&lt;p&gt;&lt;img alt="SSL certificate example" class="img-responsive" src="https://zhu45.org/images/ssl_cert.png"/&gt;&lt;/p&gt;
&lt;p&gt;With intermediate CA’s public key, client can assume the web server’s public key and information is verified by the intermediate CA. With root CA’s private key, client can assume the intermediate CA is verified by the root CA and thus, client knows the web server’s public key and information is verified by root CA and by chain of trust, web server’s SSL certificate can be trusted.&lt;/p&gt;</content><category term="2019"></category><category term="security"></category><category term="MariaDB"></category><category term="TLS"></category><category term="SSL"></category></entry><entry><title>"Ceph: A Scalable, High-Performance Distributed File System"</title><link href="https://zhu45.org/posts/2019/Jul/01/ceph-a-scalable-high-performance-distributed-file-system/" rel="alternate"></link><published>2019-07-01T16:20:00+08:00</published><updated>2019-07-01T16:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-07-01:/posts/2019/Jul/01/ceph-a-scalable-high-performance-distributed-file-system/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#additional-reading"&gt;Additional Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design a distributed file system that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;are scalable (e.g., supports hundreds of petabytes and beyond; extreme workload case)&lt;/li&gt;
&lt;li&gt;flexible to adjust to different workloads&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;while maintaining good performance?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Object-based storage (an abstraction layer between application and hard disks …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#additional-reading"&gt;Additional Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design a distributed file system that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;are scalable (e.g., supports hundreds of petabytes and beyond; extreme workload case)&lt;/li&gt;
&lt;li&gt;flexible to adjust to different workloads&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;while maintaining good performance?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Object-based storage (an abstraction layer between application and hard disks)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instead of hard disks, use intelligent object storage devices (OSD) (= CPU + network interface + local cache with an underlying disk or RAID)&lt;/li&gt;
&lt;li&gt;OSDs allows clients to read or write byte ranges to much larger (variably sized) named objects (no block-level inteface)&lt;/li&gt;
&lt;li&gt;Distribute low-level block allocation decisions to device themselves&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Traditional architecture&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Contact metadata server (MDS) for metadata ops + contact OSDS to perform file I/O&lt;/li&gt;
&lt;li&gt;Problems:&lt;ul&gt;
&lt;li&gt;Single MDS is bottleneck &lt;/li&gt;
&lt;li&gt;Traditional FS interface becomes legacy: allocation list, inode tables&lt;/li&gt;
&lt;li&gt;OSDs can do more than just storing data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Design assumptions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Large systems are built incrementally&lt;/li&gt;
&lt;li&gt;Node failures are normal&lt;/li&gt;
&lt;li&gt;Quality and character of workloads are shifting over time&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;High-level design&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace MDS with MDS cluster with dynamic metadata workload distribution&lt;/li&gt;
&lt;li&gt;Replace file allocation tables with data distribution function (e.g., CRUSH)&lt;/li&gt;
&lt;li&gt;Use OSDs for management of object replication, cluster expansion, failure detection, and recovery besides just data storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Architecture&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ceph Architecture" class="img-responsive" src="https://zhu45.org/images/ceph-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Three components:&lt;ul&gt;
&lt;li&gt;Client&lt;/li&gt;
&lt;li&gt;MDS cluster: manages namespace (file names and directories); coordinate security, consistency, and coherence&lt;/li&gt;
&lt;li&gt;OSDs cluster: stores data + metadata&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Client&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Runs on each host executing application code&lt;/li&gt;
&lt;li&gt;Expose a file system interface to applications&lt;/li&gt;
&lt;li&gt;Can be linked directly by application or mounted as a FUSE-based file system&lt;/li&gt;
&lt;li&gt;File I/O:&lt;ul&gt;
&lt;li&gt;client sends a request to MDS on file open; MDS returns file info + striping strategy (i.e., how th e file is mapped into a sequence of objects) + capability (i.e., permitted operations by clients)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Synchronization:&lt;ul&gt;
&lt;li&gt;Client I/O for the same file access has to be synchronized (i.e., blocked until acked by OSDs)&lt;/li&gt;
&lt;li&gt;For performance-focus scenaro, allow application to relax consistency by providing POSIX I/O interface extensions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;POSIX semantics require: 1. reads reflect any data previously written 2. writes are atomic (i.e., the result of overlapping, concurrent writes will reflect a particular order of occurrence)&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Namespace operations:&lt;ul&gt;
&lt;li&gt;Read operations (&lt;code&gt;readdir&lt;/code&gt;, &lt;code&gt;stat&lt;/code&gt;) and updates (&lt;code&gt;unlink&lt;/code&gt;, &lt;code&gt;chmod&lt;/code&gt;) are synchronized by MDS&lt;/li&gt;
&lt;li&gt;Optimize common metadata access pattern (&lt;code&gt;readdir&lt;/code&gt; followed by &lt;code&gt;stat&lt;/code&gt;) (trade coherence for performance)&lt;/li&gt;
&lt;li&gt;Offer POSIX interface extension (&lt;code&gt;statlite&lt;/code&gt;) for application that don’t need coherent behavior&lt;/li&gt;
&lt;li&gt;Extend existing interface for performance (&lt;code&gt;stat&lt;/code&gt; example)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Metadata management&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No file allocation metadata: object names = file inum + stripe number&lt;/li&gt;
&lt;li&gt;Objects distributed to OSDs using CRUSH&lt;/li&gt;
&lt;li&gt;Metadata storage&lt;ul&gt;
&lt;li&gt;Use journals for MSDs to stream updated metadata to the OSD cluster and for MDS failure recovery&lt;/li&gt;
&lt;li&gt;Inodes are embedded within directories, allowing the MDS to prefetch entire directories with a single OSD read request&lt;/li&gt;
&lt;li&gt;Use anchor table to keep the rare inode with multiple hard links globally addressable by inum (avoid large but sparse inode table)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dynamic Subtree Partitioning&lt;ul&gt;
&lt;li&gt;Adjustable to dynamic workloads (vs. static subtree paritioning) and maintain metadata locality and opportunities for metadata prefetching and storage (vs. hash)&lt;/li&gt;
&lt;li&gt;How it works:&lt;ul&gt;
&lt;li&gt;Each MDS measures the popularity of metadata within the directory hierarchy using counters with an exponential time decay&lt;/li&gt;
&lt;li&gt;Any operation increments the counter on the affected inode and all if its ancestors up to the root directory&lt;/li&gt;
&lt;li&gt;MDS load values (i.e., counters) are periodically compared, and appropriately-sized subtrees of the directory hierarchy are migrated to maintain load balancing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Traffic control&lt;ul&gt;
&lt;li&gt;The contents of heavily read directories (e.g., many opens) are selectively replicated across multiple nodes&lt;/li&gt;
&lt;li&gt;Directories that are particularly large or experiencing a heavy write workload (e.g., many file creations) have their contents hashed by file name across the cluster&lt;/li&gt;
&lt;li&gt;Clients can contact MDS server directly for rare metadata and are provided different MDS node for accessing popular metadata&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Dynamic Subtree Partitioning" class="img-responsive" src="https://zhu45.org/images/dynamic-subtree-partitioning.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Distributed object storage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logically as a single logical object store and namespace: Reliable Autonomic Distributed Object Store (RADOS)&lt;/li&gt;
&lt;li&gt;Data distribution with CRUSH&lt;ul&gt;
&lt;li&gt;Distributes new data randomly; migrates a random subsample of existing data to new devices; uniformly redistributes data from removed devices&lt;/li&gt;
&lt;li&gt;How it works:&lt;ul&gt;
&lt;li&gt;Ceph maps objects into placement groups (PGs) using a simple hash function, with an adjustable bit mask to control the number of PGs&lt;/li&gt;
&lt;li&gt;PGs are assigned to OSDs using CRUSH (Controlled Replication Under Scalable Hashing): a pseudo-random data distribution function that efficiently maps each PG to an ordered list of OSDs upon which to 
  store object replicas&lt;ul&gt;
&lt;li&gt;To locate any object, CRUSH requires only the placement group and an OSD cluster map: a compact, hierarchical description of the devices comprising the storage cluster&lt;/li&gt;
&lt;li&gt;Cluster map incorporates clusters physical or logical composition and potential sources of failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Replication&lt;ul&gt;
&lt;li&gt;Using a variant of primary-copy replication&lt;/li&gt;
&lt;li&gt;How it works:&lt;ul&gt;
&lt;li&gt;Data is replicated in terms of PGs, each of which is mapped to an ordered list of &lt;span class="math"&gt;\(n\)&lt;/span&gt; OSDs (for &lt;span class="math"&gt;\(n\)&lt;/span&gt;-way replication)&lt;/li&gt;
&lt;li&gt;Clients send all writes to the first non-failed OSD in an object’s PG (the &lt;em&gt;primary&lt;/em&gt;), which assigns a new version number for the object and PG and forwards the write to any additional &lt;em&gt;replica&lt;/em&gt; OSDs&lt;/li&gt;
&lt;li&gt;After each replica has applied the update and responded to the primary, the primary applies the update locally and the write is acknowledged to the client&lt;/li&gt;
&lt;li&gt;Reads are directed at the primary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data safety&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two requirements:&lt;ol&gt;
&lt;li&gt;Low-latency updates (updates should be visible to other clients asap)&lt;/li&gt;
&lt;li&gt;Data is safely replicated after writes&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;How it works:&lt;ul&gt;
&lt;li&gt;The primary forwards the update to replicas, and replies with an &lt;em&gt;ack&lt;/em&gt; after it is applied to all OSDs’ in-memory buffer caches, allowing synchronous POSIX calls on the client to return (satisfy requirement 1)&lt;/li&gt;
&lt;li&gt;A final &lt;em&gt;commit&lt;/em&gt; is sent when data is safely committed to disk (satisfy requirement 2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Data Safety Mechanism in Ceph" class="img-responsive" src="https://zhu45.org/images/data-safety-ceph.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Failure detection&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each OSD monitors those peers with which it shares PGs (existing replication traffic as liveness signal); an explicit ping is sent if an OSD has not heard from a peer recently&lt;/li&gt;
&lt;li&gt;An unresponsive OSD will have its responsbility (update serialization, replication) temporarily pass to the next OSD in each of its PGs&lt;/li&gt;
&lt;li&gt;OSD that cannot be recovered will be out of data distribution and another OSD joins to re-replicate its contents&lt;/li&gt;
&lt;li&gt;A small cluster of monitors collects failure reports and filters transient or systemic problems centrally (to ensure correct and availability of cluster map)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Recovery and cluster updates&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OSDs maintain a version number for each object and a log of recent changes for each PG&lt;/li&gt;
&lt;li&gt;On cluster updates, OSD checks local PGs and adjust itself to the new PG groups&lt;/li&gt;
&lt;li&gt;Version number is used to determine the latest PG version number&lt;/li&gt;
&lt;li&gt;Log is used to determine the correct PG contents&lt;/li&gt;
&lt;li&gt;Once OSD has the correct PG membership, each OSD independently updates its data by contacting peers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="PGs distributed to OSDs" class="img-responsive" src="https://zhu45.org/images/pg-crush.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Object storage with EBOFS&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OSD manages its local object storage with EBOFS (Extent and B-tree based Object File System)&lt;/li&gt;
&lt;li&gt;Why new file system (instead of using ext3)?&lt;ul&gt;
&lt;li&gt;POSIX interface donesn’t support atomic data and metadata update transactions&lt;/li&gt;
&lt;li&gt;High latency for journaling and synchronous writes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EBOFS &lt;ul&gt;
&lt;li&gt;User-space file system &lt;/li&gt;
&lt;li&gt;Update serialization (for synchronization) is different from on-disk commits (for safety)&lt;/li&gt;
&lt;li&gt;Supports atomic transactions (writes and attribute updates on multiple objects)&lt;/li&gt;
&lt;li&gt;update function returns when in-memory cache updated with async callbacks on commit&lt;/li&gt;
&lt;li&gt;Use B-tree to locate objects, manage block allocation, and index collections (PGs)&lt;/li&gt;
&lt;li&gt;Use extents (instead of block list) for block allocation  (for metadata compact)&lt;/li&gt;
&lt;li&gt;Free block extents are binned by size and sorted by location for locality and avoid fragmentation&lt;/li&gt;
&lt;li&gt;Metadata (execpt blokc allocation info) is in-memory&lt;/li&gt;
&lt;li&gt;Use copy-on-write&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="additional-reading"&gt;Additional Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://muratbuffalo.blogspot.com/2011/03/ceph-scalable-high-performance.html"&gt;Paper review by Murat&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category><category term="storage"></category></entry><entry><title>"Mnemosyne: Lightweight Persistent Memory"</title><link href="https://zhu45.org/posts/2019/May/07/mnemosyne-lightweight-persistent-memory/" rel="alternate"></link><published>2019-05-07T12:20:00+08:00</published><updated>2019-05-07T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-05-07:/posts/2019/May/07/mnemosyne-lightweight-persistent-memory/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design programming interface for persistent memory (i.e., storage-class memory)?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Storage-class memory (SCM) provides interface of memory (load and store instructions) but the persistence of disks&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Expose SCM as a persistent memory abstraction to provide direct access to the …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design programming interface for persistent memory (i.e., storage-class memory)?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Storage-class memory (SCM) provides interface of memory (load and store instructions) but the persistence of disks&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Expose SCM as a persistent memory abstraction to provide direct access to the durability of SCM technologies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Goals&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;User-mode access to persistence: simple for a programmer to declare data as persistent&lt;/li&gt;
&lt;li&gt;Consistent updates: support consistent modifications of data structures&lt;/li&gt;
&lt;li&gt;Conventional hardware: compatible with existing commodity processors&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Design assumptions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Assumptions about SCM&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support an atomic write of at least 64 bits&lt;/li&gt;
&lt;li&gt;Possible to stall execution until a write has made it all the way to SCM (similar to &lt;code&gt;fsync&lt;/code&gt; in FS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Failure models&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data resident in SCM survives&lt;/li&gt;
&lt;li&gt;In-flight memory operations may fail&lt;/li&gt;
&lt;li&gt;Automic updates either complete or do not modify memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Persistent regions &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Achieve 1st goal: User-mode access to persistence&lt;/li&gt;
&lt;li&gt;A segment of memory that is created and virtualized by the kernel but can be accessed directly from user mode&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Virtualize regions by&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recording the virtual-physical mapping of persistent regions in SCM&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Swapping SCM pages to backing files that it allocates when creating a region&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prevent memory leaks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Requires persistent pointer to receive memory &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Virtualizes persistent memory by swapping to files (leak does not reduce availability of persistent memory to other programs)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consistent updates&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Primary mechanism to ensure consistency: ordering writes &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Four methods&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Single variable update (atomically writing to a single variable)&lt;/li&gt;
&lt;li&gt;Append updates (log)&lt;/li&gt;
&lt;li&gt;Shadow updates (copy-on-write)&lt;/li&gt;
&lt;li&gt;In-place updates (in-place updates B-tree)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Persistent Primitives&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Achieve 2nd goal: Consistent updates&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Low-level operations that enable programmers to implement four consistency methods&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;hardware primitives for persistent write and ordering write (Single variable update)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Log facility (append-only updates)&lt;/li&gt;
&lt;li&gt;Persistent heap for allocating small blocks of memory (shadow updates)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Durable memory transactions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Achieve 2nd goal: Consistent updates&lt;/li&gt;
&lt;li&gt;Support in-place updates&lt;/li&gt;
&lt;li&gt;Use compiler to convert C/C++ code into transactions to ensure atomicity, durability, and isolation (=&amp;gt; transactions allow concurrent update to different data structures)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hardware Primitives&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Achieve 3rd goal: Conventional hardware&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use three hardware primitives from processors&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;write-through stores: write data directly to memory rather than to the cache&lt;/li&gt;
&lt;li&gt;fences: prevent subsequent writes from completing before preceding writes&lt;/li&gt;
&lt;li&gt;flushes: writes a cahce line out to memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Architecture&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="mnemosyne architecture" class="img-responsive" src="https://zhu45.org/images/mnemosyne-arch.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Implementation highlights&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use tornbit in raw word log (RAWL) to use only one fence to solve “torn write” problem (compares with two fence &amp;amp; checksum approach, better performance)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="tornbit RAWL solution" class="img-responsive" src="https://zhu45.org/images/tornbit.png"/&gt; &lt;/p&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing"</title><link href="https://zhu45.org/posts/2019/May/06/resilient-distributed-datasets-a-fault-tolerant-abstraction-for-in-memory-cluster-computing/" rel="alternate"></link><published>2019-05-06T20:24:00+08:00</published><updated>2019-05-06T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-05-06:/posts/2019/May/06/resilient-distributed-datasets-a-fault-tolerant-abstraction-for-in-memory-cluster-computing/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#goal"&gt;Goal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#resilient-distributed-datasets-rdd"&gt;Resilient Distributed Datasets (RDD)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a system that support in-memory computation (with real-time interaction support) in large cluster efficiently with fault-tolerance?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prior systems are lack of abstraction for leveraging distributed memory (intermediate computing result reuse is problem: has to save and then read …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#goal"&gt;Goal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#resilient-distributed-datasets-rdd"&gt;Resilient Distributed Datasets (RDD)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a system that support in-memory computation (with real-time interaction support) in large cluster efficiently with fault-tolerance?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prior systems are lack of abstraction for leveraging distributed memory (intermediate computing result reuse is problem: has to save and then read through storage system)&lt;/li&gt;
&lt;li&gt;Prior systems on data reuse do not have abstraction for general use (i.e., limited computatin pattern supported) and do not support real-time interaction (e.g., load data sets into memory and query them interactively)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;h3 id="goal"&gt;Goal&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Provide distribued memory abstractions for clusters to support apps with working sets&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Retain the attactive properties of MapReduce:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fault tolerance (for crashes &amp;amp; stragglers)&lt;/li&gt;
&lt;li&gt;Data locality&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="resilient-distributed-datasets-rdd"&gt;Resilient Distributed Datasets (RDD)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Generality conjecture: Spark’s data flow + RDDs unifies many proposed cluster programming models (MapReduce, Dryad, SQL, Pregel (BSP), HaLoop (iterative MR), Continuous Bulk Processing)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An RDD is a read-only, partitioned, logical collection of records&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need not be materialized, but rather contains information to rebuild a dataset from stable storage&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Coarse-grained transformations (e.g., map, filter, join)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;efficiently fault-tolerant: logging the transformations used to build a dataset (its lineage) rather than the actual data&lt;/li&gt;
&lt;li&gt;vs. actions: operations that return a value to the application or export data to a storage system (e.g., count, collect, save)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Created through transformations on 1) data in storage 2) other RDDs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;User can specify which RDD to reuse and how to store it&lt;/li&gt;
&lt;li&gt;User can partition RDD across machines on a key&lt;/li&gt;
&lt;li&gt;vs. distributed shared memory (DSM)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="RDD vs. DSM" class="img-responsive" src="https://zhu45.org/images/rdd-dsm.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can use persist method to indicate which RDDs the user want to reuse in future operations and specify persistence priority (e.g., which in-memory data should store to disk first) and persistence strategy (e.g., store RDD on disk instead of memory; replication)&lt;/li&gt;
&lt;li&gt;Target application: iterative algorithms and iterative data mining tools&lt;/li&gt;
&lt;li&gt;Limitation: not suitable for applications that make asynchronous fine-grained updates to shared state (e.g., storage system for a web app or an incremental web crawler)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Representing RDD by exposing information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;parititions of datasets&lt;/li&gt;
&lt;li&gt;dependencies on parent RDDs (narrow vs. wide) (see figure below)&lt;/li&gt;
&lt;li&gt;partition-based function for computing the dataset&lt;/li&gt;
&lt;li&gt;metadata on partitioning shceme and data placement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="narrow vs. wide dependencies" class="img-responsive" src="https://zhu45.org/images/narrow-wide.png"/&gt;&lt;/p&gt;</content><category term="2019"></category><category term="papers"></category><category term="distributed systems"></category><category term="os"></category></entry><entry><title>"GPUfs: Integrating a File System with GPUs"</title><link href="https://zhu45.org/posts/2019/May/06/gpufs-integrating-a-file-system-with-gpus/" rel="alternate"></link><published>2019-05-06T12:20:00+08:00</published><updated>2019-05-06T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-05-06:/posts/2019/May/06/gpufs-integrating-a-file-system-with-gpus/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;GPU data access needs explicit management by each individual GPU program. How can we provide an illusion similar to VM to physical pages such that
all the data access can be done automatically (i.e., without stating that how data should be fetched from host …&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;GPU data access needs explicit management by each individual GPU program. How can we provide an illusion similar to VM to physical pages such that
all the data access can be done automatically (i.e., without stating that how data should be fetched from host storage explicitly)? Clearly, FS is a good abstraction
but how can we adapt such interface to GPU application needs while maintaining good performance?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Motivation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPUs have no direct access to files on the host OS file system; developers manage data movement explicitly between CPU main memory and GPU local memory&lt;/li&gt;
&lt;li&gt;Offloading computations to GPU (common application) under GPU-as-coprocessor programming model introduces overhead due to the GPU kernel start/termination&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Offloading computation to GPU overhead" class="img-responsive" src="https://zhu45.org/images/co-processor.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;About GPU&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPUs are multicore processors&lt;/li&gt;
&lt;li&gt;Each core called multiprocessor (MP), features a wide SIMD vector unit, which a hardware scheduler multiplexes between multiple execution contexts&lt;/li&gt;
&lt;li&gt;Thread: a GPU’s basic sequential unit of execution (higher execution units: warps, threadblock, kernel)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="GPU execution hierarchy" class="img-responsive" src="https://zhu45.org/images/gpu-execution.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Application point of view&lt;/p&gt;
&lt;p&gt;&lt;img alt="GPUfs: application point of view" class="img-responsive" src="https://zhu45.org/images/gpufs-app-view.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Architecture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="GPUfs architecture" class="img-responsive" src="https://zhu45.org/images/gpufs-arch.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPU programs can access the host’s file system via a GPUfs library linked into the application’s GPU code&lt;/li&gt;
&lt;li&gt;GPUfs library works with the host OS on the CPU to coordinate the file system’s namespace and data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Design principles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Data parallelism&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All application threads in a warp must invoke the same GPUfs call, with the same arguments, at the same point in application code&lt;/li&gt;
&lt;li&gt;Minimize per-open file state (e.g., remove seek pointers)&lt;/li&gt;
&lt;li&gt;Separate &lt;code&gt;sync&lt;/code&gt; from &lt;code&gt;close&lt;/code&gt; (i.e., &lt;code&gt;close&lt;/code&gt; call will not trigger &lt;code&gt;sync&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Constrain &lt;code&gt;mmap&lt;/code&gt; semantics to avoid the need for complex memory management on critical data parallel paths&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Access locality&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implements a weak consistency model similar to the private workspace model in AFS (i.e., sync-to-open semantics)&lt;/li&gt;
&lt;li&gt;Local file modifications propagate to main CPU memory only when the application explicitly &lt;code&gt;sync&lt;/code&gt; the file with storage. &lt;/li&gt;
&lt;li&gt;Modification is visible to other GPUs during re-open the file&lt;/li&gt;
&lt;li&gt;Allow concurrent non-overlapping writes to the same file (i.e., undefined results for overlapping writes)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;API design highlights&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Open: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All GPUfs threads opening the same file obtain a single shared file descriptor (increments reference counts on file descriptor)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read and write: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;File descriptors have no seek pointers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Close and sync:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;glcose&lt;/code&gt; does not propage locally writen data back to the CPU, or to other GPUs, until the application explicitly synchronize file data by calling &lt;code&gt;sync&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;File mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No guarantee to map the entire requested file region&lt;/li&gt;
&lt;li&gt;No guarantee on mapping at a particular address (&lt;code&gt;MMAP_FIXED&lt;/code&gt; unsupport)&lt;/li&gt;
&lt;li&gt;No guarantee returns the requested permission (ask read may return read/write)&lt;/li&gt;
&lt;li&gt;Benefits: allow GPUfs to give the application pointers directly into GPU-local buffer cache pages, residing the same address space as the application’s GPU code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implementation&lt;/p&gt;
&lt;p&gt;&lt;img alt="GPUfs software layers" class="img-responsive" src="https://zhu45.org/images/gpufs-software-layer.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Top layer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Runs in the context of the application’s GPU kernels and maintains its data structures in GPU memory&lt;/li&gt;
&lt;li&gt;Implements the GPUfs API, tracks open file state, and implements buffer cache and paging&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Communication layer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manages GPU-CPU communications&lt;/li&gt;
&lt;li&gt;Data structures shared between the GPU and CPU are stored in write-shared CPU memory accessible to both devices&lt;/li&gt;
&lt;li&gt;Implements a GPU-CPU RPC infrastructure (need hardware support: GPU-CPU memory fences; GPU cahce bypass)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consistency layer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS kernel module running on the host CPU, which manages consistency between the host OS’s CPU buffer cache and the GPU buffer caches&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="gread implementation" class="img-responsive" src="https://zhu45.org/images/gread.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On-demand data transfer&lt;/p&gt;
&lt;p&gt;&lt;img alt="on-demand data transfer" class="img-responsive" src="https://zhu45.org/images/gpufs-on-demand.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple CPU code&lt;/li&gt;
&lt;li&gt;Handle data that is greater than GPU memory (use buffer cache)&lt;/li&gt;
&lt;li&gt;Enable long-running kernels&lt;/li&gt;
&lt;li&gt;Pay-as-you-go performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memory overhead&lt;/li&gt;
&lt;li&gt;Register pressure&lt;/li&gt;
&lt;li&gt;Idiosyncratic API&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Dandelion: a Compiler and Runtime for Heterogeneous Systems"</title><link href="https://zhu45.org/posts/2019/May/06/dandelion-a-compiler-and-runtime-for-heterogeneous-systems/" rel="alternate"></link><published>2019-05-06T10:00:00+08:00</published><updated>2019-05-06T10:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-05-06:/posts/2019/May/06/dandelion-a-compiler-and-runtime-for-heterogeneous-systems/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#architecture"&gt;Architecture&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#dandelion-compilers"&gt;Dandelion Compilers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dandelion-runtime"&gt;Dandelion Runtime&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a system that provides programmability for heterogeneous distributed systems?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Challenges are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Heterogeneous: different programming models, architecture expertise&lt;/li&gt;
&lt;li&gt;Distributed resources: data movement, scheduling&lt;/li&gt;
&lt;li&gt;Concurrency: synchronization, consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;h3 id="overview"&gt;Overview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Goals: make it simple for programmers to write high …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#architecture"&gt;Architecture&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#dandelion-compilers"&gt;Dandelion Compilers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dandelion-runtime"&gt;Dandelion Runtime&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a system that provides programmability for heterogeneous distributed systems?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Challenges are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Heterogeneous: different programming models, architecture expertise&lt;/li&gt;
&lt;li&gt;Distributed resources: data movement, scheduling&lt;/li&gt;
&lt;li&gt;Concurrency: synchronization, consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;h3 id="overview"&gt;Overview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Goals: make it simple for programmers to write high performance applications for hetergeneous system on a small cluster with GPUs and leverage its available resources&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Single programming interface for clusters with CPUs, GPUs, FPGAs, etc&lt;/li&gt;
&lt;li&gt;“Single machine” programming model: programmer writes sequential code&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Runtime: take sequential program and do the following whenever possible&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parallize computation&lt;/li&gt;
&lt;li&gt;Partition data&lt;/li&gt;
&lt;li&gt;Runs on all available resources&lt;/li&gt;
&lt;li&gt;Maps computation to best architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Workflow&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Given User program &amp;amp; partitioned data files as input&lt;/li&gt;
&lt;li&gt;Compile to a mix of CPU and GPU code and run on the cluster (Dandelion role)&lt;/li&gt;
&lt;li&gt;Output result as partitioned data files&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Challenges&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple programming model&lt;/li&gt;
&lt;li&gt;Integerate multiple runtime efficiently to enable high performance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dandelion innovation by levels&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Programming languages&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adopt language integration approach (LINQ): extends with Dandelion specific operators&lt;/li&gt;
&lt;li&gt;Constraints: UDF must be side-effect free; execute .NET function with dynamic memory allocation on CPUs only&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compilers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatically compiles a data-parallel program to run on distributed heterogeneous systems&lt;/li&gt;
&lt;li&gt;Translation of .NET byte-code to multiple backends (e.g., GPU, FPGA)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Distributed and parallel runtime&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Treat hetergeneous system as the composition of a collection dataflow engines&lt;/li&gt;
&lt;li&gt;Three dataflow engines: cluster, mult-core CPU, and GPU (e.g., use PTask)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="architecture"&gt;Architecture&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Dandelion Architecture" class="img-responsive" src="https://zhu45.org/images/dandelion-arch.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two main components&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dandelion compiler generates the execution plans and the worker code to be run on the CPUs and GPUs of cluster machines&lt;/li&gt;
&lt;li&gt;Dandelion runtime uses the execution plans to manage the computation on the cluster (e.g., scheduling, distribution)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="dandelion-compilers"&gt;Dandelion Compilers&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dandelion compiler generates CUDA code, and three levels of dataflow graphs to orchestrate the execution&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Relies on a library of generic primitives (GPU primitive library) to construct execution plans&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;GPU primitive library: for GPU dataflow graph&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;primitives include low level building blocks (e.g., parallel scan and hash tables), high-level primitives for relational operators (e.g., groupby and join)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compiling C# to GPU code&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Translation performed at .NET byte-code level&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Map C# types to CUDA structs&lt;/li&gt;
&lt;li&gt;Translate C# methods into CUDA kernel functions&lt;/li&gt;
&lt;li&gt;Generate C# code for CPU-GPU serialization/transfer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Main constraint: dynamic memory allocation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Convert to stack allocation if object size can be inferred&lt;/li&gt;
&lt;li&gt;Fail parallelization, fallback to host otherwise&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use Common Compiler Infrastructure (CGI) framework for the intermediate AST&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="dandelion-runtime"&gt;Dandelion Runtime&lt;/h4&gt;
&lt;p&gt;&lt;img alt="Dandelion dataflow graph" class="img-responsive" src="https://zhu45.org/images/dandelion-dataflow.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dataflow graphs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vertex: a fragment of the computation&lt;/li&gt;
&lt;li&gt;Edge: communication channels&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Three levels: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cluster level (what machine to compute what): cluster execution engine assigns vertices to available machines and distributes code and graphs, orchestrating the computation&lt;/li&gt;
&lt;li&gt;machine level (how the computation is done on each machine): executes its own dataflow graph, managing input/output and execution threads&lt;/li&gt;
&lt;li&gt;GPU level (use PTask as GPU dataflow engine)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Three dataflow graphs (shown above) form the Dandelion runtime, and the composition
of those graphs forms the global dataflow graph for the entire computation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cluster dataflow engine (“Moxie”)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allows the entire computation to stay in memory when the aggregate cluster memory is sufficient (assume work on a small cluster with powerful machines with GPUs)&lt;/li&gt;
&lt;li&gt;Holds intermediate data in memory and can checkpoint them to disk (like Spark)&lt;/li&gt;
&lt;li&gt;Aggressively caches in-memory datasets (including intermediate data)&lt;/li&gt;
&lt;li&gt;Uses async. checkpoints to support coarse-grained fault tolerance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Machine dataflow engine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vertex: a unit of computation can be executed on CPU or GPU&lt;/li&gt;
&lt;li&gt;For CPU: parallelize the computation on multi-core&lt;/li&gt;
&lt;li&gt;For GPU: dispatch computation to GPU dataflow engine&lt;/li&gt;
&lt;li&gt;Async channels are created to transfer data between the CPU and GPU memory spacs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GPU dataflow engine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use PTask execution engine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a token model dataflow system&lt;/li&gt;
&lt;li&gt;tasks: computation or nodes in the graph&lt;/li&gt;
&lt;li&gt;ports: inputs and outputs of the tasks&lt;/li&gt;
&lt;li&gt;Channels: connects ports&lt;/li&gt;
&lt;li&gt;datablocks: deseralized data into chunks that are moved through channels&lt;/li&gt;
&lt;li&gt;Computation are done by pushing and pulling datablocks to and from channels (Future)&lt;/li&gt;
&lt;li&gt;A task is ready for execution when all of its input ports have available datablocks and all of its output ports have capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="papers"></category><category term="os"></category></entry><entry><title>"Operating System Transactions"</title><link href="https://zhu45.org/posts/2019/Apr/27/operating-system-transactions/" rel="alternate"></link><published>2019-04-27T12:20:00+08:00</published><updated>2019-04-27T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-04-27:/posts/2019/Apr/27/operating-system-transactions/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-transactions"&gt;System transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#txos"&gt;TxOS&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#design"&gt;Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation"&gt;Implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to implement transaction with ACID guarantee in OS to provide concurrency control?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Problems that can be solved by using transactions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security vulnerbilities in the file system that are caused by time-of-check-to-time-of-use (TOCTTOU) race conditions&lt;/li&gt;
&lt;li&gt;Unsuccessful software installation …&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-transactions"&gt;System transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#txos"&gt;TxOS&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#design"&gt;Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation"&gt;Implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to implement transaction with ACID guarantee in OS to provide concurrency control?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Problems that can be solved by using transactions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Security vulnerbilities in the file system that are caused by time-of-check-to-time-of-use (TOCTTOU) race conditions&lt;/li&gt;
&lt;li&gt;Unsuccessful software installation is hard to roll back without disturbing concurrent, independent updates to the file system&lt;/li&gt;
&lt;li&gt;Consistency problem in managing local user accounts&lt;/li&gt;
&lt;li&gt;Have to use a database for concurrency management and crash consistency, which lead to more complex application code and system administration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;h3 id="overview"&gt;Overview&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;System transactions allow programmers to group accesses to system resources into logical units that are executed with ACID guarantee&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;sys_xbegin()&lt;/code&gt; and &lt;code&gt;sys_xend()&lt;/code&gt; to wrap around code regions with consistency constraints&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;sys_xabort()&lt;/code&gt; to abort in-progress transaction&lt;/li&gt;
&lt;li&gt;Access and modify to system resources are kept isolated until commit time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="TxOS API" class="img-responsive" src="https://zhu45.org/images/txos-api.png"/&gt;&lt;/p&gt;
&lt;h3 id="system-transactions"&gt;System transactions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;System transactions provide ACID semantics for updates to OS resources (e.g., files, pipes, and signals)&lt;/li&gt;
&lt;li&gt;OS is responsible for ensuring that transactional &amp;amp; non-transactional access to system state are correctly serialized and contention is arbitrated fairly&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To ensure isolation, kernel enforces the invariant that a kernel object may only have one writer at a time (except containers)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Concurrent system transactions that modify the same kernel object cannot commit (i.e., one of them has to abort)&lt;/li&gt;
&lt;li&gt;Non-transactional updates to objects read or written by an active system transaction are also forbidden&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Durability is optional (for performance concern)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Provides strong isolation: serialization of transactional and non-transactional updates to the same resources&lt;/li&gt;
&lt;li&gt;OS always chooses the same transaction to restart when hit the conflict that involves the same transactions (to prevent livelock)&lt;/li&gt;
&lt;li&gt;ACID is guaranteed for system state, not application state&lt;/li&gt;
&lt;li&gt;Communication outside of a trasnaction violates isolation and thus not supported (e.g., IPC between a thread executing a system transaction and a non-transactional thread)&lt;/li&gt;
&lt;li&gt;Communication among threads within the same transaction is unrestricted&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="txos"&gt;TxOS&lt;/h3&gt;
&lt;h4 id="design"&gt;Design&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;High-level overview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Application updates usually go to OS buffer first; copy-on-write these buffers for transactions to support isolation&lt;/li&gt;
&lt;li&gt;Transactional updates to kernel data structures are supported through object-based software transactional memory systems&lt;/li&gt;
&lt;li&gt;Isolation mechanism is optimistic: assume conflicts are rare&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Interoperability and fairness&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TxOS prvoides strong isolation inside the kernel by requiring all system calls to follow the same locking discipline and transactions need to anonotate accessed kernel objects (all threads, whether transactional or not, need to check for conflict on 1st time access)&lt;/li&gt;
&lt;li&gt;Scheduler can maintain fairness between non-transactional and transactional threads b/c conflict is detected before threads entering a critical region and suspension of non-transactional thread is possible&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Managing transactional state&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lazy version management: transactions operate on private copies of a data structure (vs. eager version management: in-place data update + undo log)&lt;/li&gt;
&lt;li&gt;TxOS holds lock only to make a private copy of the data structure (enforcing global ordering of kernel locks avoid deadlock)&lt;/li&gt;
&lt;li&gt;Commit latency is challenge for lazy version management: TxOS minimizes this overhead by splitting objects, tunning a &lt;code&gt;memcpy&lt;/code&gt; of the entire object into a pointer copy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TxOS provides transaction to system states; User-level transactional memory (TM) system provides transaction to application states (integrate together to provide a complete transactional programming model)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implementation"&gt;Implementation&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Versioning data:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TxOS maintains multiple versions of kernel data structures to isolate the system calls effect until transactions commit and easy abort&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Split objects into header and data so that TxOS maintains the invariant: single writer to any object (i.e., concurrent writes must be on disjoint objects) (see Figure 2 below)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Object header contains a pointer to object’s data; transactions commit changes to an object by replacing this pointer in the header to a modified copy of data object&lt;/li&gt;
&lt;li&gt;Header itself is never replaced by a transaction (eliminates the need to update pointers in other objects)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No need to recursively update pointers in other objects&lt;/li&gt;
&lt;li&gt;Avoid restarting active transactions tiggered by the kernel garbage collection thread&lt;/li&gt;
&lt;li&gt;Ensure that transactional code always has a speculative object&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TxOS decomposes an object into multiple data payloads when it houses data that can be accessed disjointly&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No copies are made for kernel objects that are read-only in transactions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writer creates a new object copy when transactional reader reference count is non-zero and install it as new stable version&lt;/li&gt;
&lt;li&gt;Old copy is collected via read-copy update (RCU)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="TxOS Object Splitting" class="img-responsive" src="https://zhu45.org/images/txos-split.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Conflict detection and resolution&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tx_data&lt;/code&gt; object (part of transaction-supported kernel objects) contains a pointer to a transactional writer list and a pointer to a transactional reader list (non-null indicates there is an active treansactional writer/reader)&lt;/li&gt;
&lt;li&gt;Use locks and test on the transactional writers and readers fileds to detect transactional and asymmetric (conflict involve transaction and non-transaction threads) conflicts&lt;/li&gt;
&lt;li&gt;Selects the process with the higher scheduling priority as the winnder of a conflict (if priority equal, older transaction wins)&lt;/li&gt;
&lt;li&gt;Non-transactional thread is preempted when asymmetric conflict is detected and rescheduled when the conflicting transaction is commited&lt;/li&gt;
&lt;li&gt;Table 3 shows the transactional list state that minimizes the conflicts involving updating linked list data structure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="TxOS transactional list state" class="img-responsive" src="https://zhu45.org/images/txos-list.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Managing transaction state&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use transaction objects to store metadata and statistics for a transaction; let kernel thread’s control block pointing to it&lt;/li&gt;
&lt;li&gt;Transaction status (&lt;code&gt;status&lt;/code&gt;) is checked and updated atomically&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Abort is invoked when conflict is detected during transactional system call:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transaction stores register state on the stack at the beginning of the current system call&lt;/li&gt;
&lt;li&gt;On abort, register state is restored and execution is jumped back to the top of kernel stack&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Need to keep track of deferred operations (done until the commit time) (e.g., free memory, deliver signals, file system monitoring events)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;A workset maintains references to all kernel objects that transaction has made a copy of&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="TxOS transaction object" class="img-responsive" src="https://zhu45.org/images/txos-state.png"/&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Commit protocol&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Transaction acquires locks for all items in its workset&lt;/li&gt;
&lt;li&gt;TxOS iterates over the objects in workset twice: 1) acquire the blocking locks 2) acquire non-blocking locks&lt;/li&gt;
&lt;li&gt;Transaction checks the &lt;code&gt;status&lt;/code&gt; and see if it can commit&lt;/li&gt;
&lt;li&gt;Transaction copies its updates to the stable objects&lt;/li&gt;
&lt;li&gt;Release spinlocks&lt;/li&gt;
&lt;li&gt;Perform deferred operations&lt;/li&gt;
&lt;li&gt;Release mutex&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="TxOS commit protocol" class="img-responsive" src="https://zhu45.org/images/txos-commit-protocol.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Abort protocol&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Release any kernel locks&lt;/li&gt;
&lt;li&gt;Iterate workset and locks each objects to remove any references to itself from the object’s transactional state and then unlocks the object&lt;/li&gt;
&lt;li&gt;Transaction frees its shadow objects and decrements the reference count on their stable counterparts&lt;/li&gt;
&lt;li&gt;Release any resources used in transaction (e.g., memory allocation)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;User-level transactions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Commit protocol&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The user prepares a Transaction&lt;/li&gt;
&lt;li&gt;The user requests that the system commit the transaction through &lt;code&gt;sys_xend()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;System commits or aborts&lt;/li&gt;
&lt;li&gt;System communicates the result to user as &lt;code&gt;sys_xend()&lt;/code&gt; return code&lt;/li&gt;
&lt;li&gt;User commits or aborts accordingly&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;multi-process transactions, and signal delivery can be checked in paper&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Scheduler Activations: Effective Kernel Support for the User-Level Management of Parallelism"</title><link href="https://zhu45.org/posts/2019/Apr/13/scheduler-activations-effective-kernel-support-for-the-user-level-management-of-parallelism/" rel="alternate"></link><published>2019-04-13T12:20:00+08:00</published><updated>2019-04-13T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-04-13:/posts/2019/Apr/13/scheduler-activations-effective-kernel-support-for-the-user-level-management-of-parallelism/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#theme-for-supporting-concurrent-and-parallel-programming"&gt;Theme for supporting concurrent and parallel programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#heavyweight-process-model"&gt;“Heavyweight” Process Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lightweight-user-level-threads"&gt;“Lightweight” User-level Threads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#kernel-threads"&gt;Kernel Threads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#user-level-threads-multiplexed-on-kernel-threads"&gt;User-level threads multiplexed on kernel threads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User-level library&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Management in application’s address space&lt;/li&gt;
&lt;li&gt;High performance and very flexible&lt;/li&gt;
&lt;li&gt;Lack functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operating system kernel&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Poor performance (compared with user-level …&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#theme-for-supporting-concurrent-and-parallel-programming"&gt;Theme for supporting concurrent and parallel programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#heavyweight-process-model"&gt;“Heavyweight” Process Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lightweight-user-level-threads"&gt;“Lightweight” User-level Threads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#kernel-threads"&gt;Kernel Threads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#user-level-threads-multiplexed-on-kernel-threads"&gt;User-level threads multiplexed on kernel threads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User-level library&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Management in application’s address space&lt;/li&gt;
&lt;li&gt;High performance and very flexible&lt;/li&gt;
&lt;li&gt;Lack functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Operating system kernel&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Poor performance (compared with user-level threads)&lt;/li&gt;
&lt;li&gt;Poor flexibility&lt;/li&gt;
&lt;li&gt;High functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How to design a parallelism mechanism (e.g., kernel interface + use-level thread package) that 
combines the functionality of kernel threads with the performance and flexibility of user-level threads?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;h3 id="theme-for-supporting-concurrent-and-parallel-programming"&gt;Theme for supporting concurrent and parallel programming&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Conform to application semantics&lt;/li&gt;
&lt;li&gt;Respect priorities of applications&lt;/li&gt;
&lt;li&gt;No unnecessary blocking&lt;/li&gt;
&lt;li&gt;Fast context switch&lt;/li&gt;
&lt;li&gt;High processor utilization&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="heavyweight-process-model"&gt;“Heavyweight” Process Model&lt;/h3&gt;
&lt;p&gt;&lt;img alt="process model" class="img-responsive" src="https://zhu45.org/images/process-model.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple, uni-threaded model&lt;/li&gt;
&lt;li&gt;Security provided by address space boundaries&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High cost for context switch&lt;/li&gt;
&lt;li&gt;Coarse granualarity limits degree of concurrency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="lightweight-user-level-threads"&gt;“Lightweight” User-level Threads&lt;/h3&gt;
&lt;p&gt;&lt;img alt="user-level thread" class="img-responsive" src="https://zhu45.org/images/user-level-thread.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thread semantics defined by application: different applications can be linked with different user-level thread libraries&lt;/li&gt;
&lt;li&gt;Fast context switch time: within an order of magnitude of procedure call time&lt;/li&gt;
&lt;li&gt;No kernel intervention (i.e., high performance)&lt;/li&gt;
&lt;li&gt;Good scheduling policy flexibility: done by the thread lib&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unnecessary blocking: A blocking system call, I/O, page faults, and multiprogramming block all threads (i.e., lack of functionality)&lt;/li&gt;
&lt;li&gt;System scheduler unaware of user thread priorities&lt;/li&gt;
&lt;li&gt;Processor under-utilization (i.e., Hard to run as many threads as CPUs) because: Don’t know how many CPUs; Don’t know when a thread blocks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="kernel-threads"&gt;Kernel Threads&lt;/h3&gt;
&lt;p&gt;&lt;img alt="kernel thread" class="img-responsive" src="https://zhu45.org/images/kernel-thread.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;No system integration problems (system calls can be blocking calls) (i.e., high functionality)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Handle blocking system calls/page faults well&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Threads are seen and scheduled only by the kernel&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adds many user/kernel crossings (i.e., low performance) (e.g., thread switch, create, exit, lock, signal, wait, …)&lt;ul&gt;
&lt;li&gt;Typically 10x-30x slower than user threads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Every thread-related call traps: etra kernel trap and copy and check of all parameters on all thread operations&lt;/li&gt;
&lt;li&gt;Single, general purpose scheduling algorithm (i.e., lack of flexibility)&lt;/li&gt;
&lt;li&gt;Thread semantics defined by system&lt;/li&gt;
&lt;li&gt;Context switch time better than process switch time by an order of magnitude, but an order of magnitude worse than user-level threads&lt;/li&gt;
&lt;li&gt;System scheduler unaware of user thread state (e.g., in critical section) leading to blocking and lower processor utilization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="user-level-threads-multiplexed-on-kernel-threads"&gt;User-level threads multiplexed on kernel threads&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Question: Can we accomplish system integration by implementing user-level threads on top of kernel threads?&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Different apps have different needs (thread priorities, etc)&lt;/li&gt;
&lt;li&gt;Insufficient visibility between the kernel and user thread library&lt;ul&gt;
&lt;li&gt;Kernel doesn’t know best thread to run&lt;/li&gt;
&lt;li&gt;Kernel doesn’t know about user-level locks, priority inversion (preempt while in critical section): too much info changing too quickly to notify kernel&lt;/li&gt;
&lt;li&gt;kernel events (preemption, I/O) invisible to user library (user thread blocks, then kernel thread serving it also blocks)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Kernel threads are scheduled obliviously w.r.t user-level thread library&lt;/li&gt;
&lt;li&gt;Hard to keep same number of kthreads as CPUs&lt;ul&gt;
&lt;li&gt;Neither kernel nor user knows how many runnable threads&lt;/li&gt;
&lt;li&gt;User doesn’t even know number of CPUs available&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Can have deadlock&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Key problem: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Application has knowledge of the user-level thread state but has little knowledge of or influence over critical kernel-level events (this is by design to achieve the virtual machine abstraction)&lt;/li&gt;
&lt;li&gt;Kernel has inadequate knowledge of user-level thread state to make optimal scheduling decisions&lt;ul&gt;
&lt;li&gt;Kernel may de-scehdule a thread at a bad time (e.g., while holding a lock)&lt;/li&gt;
&lt;li&gt;Application may need more or less computing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A mechanism that facilitates exchange of information between user-level and kernel-level mechanisms&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;A general system design problem: communicating information and control across layer boundaries while preserving the inherent
advantages of layering, abstraction, and virtualization.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;What is a SA?&lt;ul&gt;
&lt;li&gt;Execution context for running user-level threads&lt;/li&gt;
&lt;li&gt;Notifies the user-level thread system of kernel event&lt;/li&gt;
&lt;li&gt;Provides space for the kernel to save processor context&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;A scheduler activation is the execution context for vectoring control from the kernel to the address space on a kernel event. The address space thread scheduler uses this context to handle the event, e.g., to modify user-level thread data structures, to execute user-level threads, and to make requests of the kernel. &lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Scheduler Activations (SA) structure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="scheduler activation" class="img-responsive" src="https://zhu45.org/images/scheduler-activation.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SA basics&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Multi-threaded programs given an address space (as usual)&lt;/li&gt;
&lt;li&gt;Facilitate flow of key information between user space and kernel space&lt;/li&gt;
&lt;li&gt;Kernel explicitly “vectors” kernel events to the user-level thread via SA&lt;/li&gt;
&lt;li&gt;Extended kernel interface for processor allocation-related events&lt;ul&gt;
&lt;li&gt;User-level thread library notifies the kernel about events&lt;/li&gt;
&lt;li&gt;Kernel uses the SA itself to do the same&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SA has two execution stacks&lt;ul&gt;
&lt;li&gt;The kernel stack - used by the user-level thread when running in the kernel mode (e.g., system call)&lt;/li&gt;
&lt;li&gt;The user stack - used by the user-level thread scheduler&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Each user-level thread is given a separate stack so that the thread scheduler can resume running if a user-level thread blocks&lt;/li&gt;
&lt;li&gt;The kernel-level SA communicates with the user-level library by upcalls&lt;/li&gt;
&lt;li&gt;When must kernel call into user-space? (Table II)&lt;ul&gt;
&lt;li&gt;New processor available&lt;/li&gt;
&lt;li&gt;Processor had been preempted&lt;/li&gt;
&lt;li&gt;Thread has blocked&lt;/li&gt;
&lt;li&gt;Thread has unblocked&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When must user call into kernel? (Table III)&lt;ul&gt;
&lt;li&gt;Need more CPUs&lt;/li&gt;
&lt;li&gt;CPU is idle&lt;/li&gt;
&lt;li&gt;Preempt thread another CPU (for higher priority thread)&lt;/li&gt;
&lt;li&gt;Return unused SA for recycling (after user-level thread system has extracted necessary state)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SA role: there is one running SA for each processor assigned to the user process&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="SA role" class="img-responsive" src="https://zhu45.org/images/scheduler-activation-role.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SA lifecycle&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On program start:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;New SA is created, assigned a processor and “upcalled” (fixed entry point)&lt;/li&gt;
&lt;li&gt;User-level thread scheduler initializes and runs on this SA&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kernel uses SA to notify the user-level about important events: preemption, I/O, page faults&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoiding effects of blocking&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="SA blocking" class="img-responsive" src="https://zhu45.org/images/scheduler-activation-blocking.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Resume blocked thread&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="SA blocked resume" class="img-responsive" src="https://zhu45.org/images/sa-blocked-resume.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I/O request/completion&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="SA io" class="img-responsive" src="https://zhu45.org/images/SA-io.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Responsibility division between kernel and application address space:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Processor allocation (the allocation of processors to address space) is done by the kernel.&lt;/li&gt;
&lt;li&gt;Thread scheduling (the assignment of an address space’s threads to its processors) is done by each address space.&lt;/li&gt;
&lt;li&gt;The kernel notifies the address space thread scheduler of every event affecting the address space.&lt;/li&gt;
&lt;li&gt;The address space notifies the kernel of the subset of user-level events that can affect processor allocation decisions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SA vs. kernel threads key differences&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Preempted threads never resumed by the kernel directly (rather, indirectly through an SA)&lt;/li&gt;
&lt;li&gt;A traditional kernel:&lt;ul&gt;
&lt;li&gt;Directly resumes the kernel thread&lt;/li&gt;
&lt;li&gt;Does NOT notify the user-thread about preemption&lt;/li&gt;
&lt;li&gt;Does NOT notify the user-thread about resumption&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Critical section&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Problem: threads preempted while holding a lock, which can lead to deadlock&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User-level thread holds lock on the program’s ready list&lt;/li&gt;
&lt;li&gt;Gets preempted&lt;/li&gt;
&lt;li&gt;Thread scheduler tries put that thread in the ready list on SA upcall&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use recovery (recover when it does)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Thread scheduler checks to see if the thread was executing in a critical section&lt;/li&gt;
&lt;li&gt;If so, the thread is continued temporarily via a user-level context switch. When the continued thread exits the critical section, it relinquishes control back to the original upcall, again via a user-level context switch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Others&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Page faults must be handled carefully: the kernel must notify the program of a page fault only when the page fault is serviced&lt;/li&gt;
&lt;li&gt;User-level thread after blocking might still execute in kernel (e.g., I/O completing): the kernel notifies the user-level only after the user thread is in a “safe” point&lt;/li&gt;
&lt;li&gt;Every SA needs a processor to do the up-call on: at time T3 of I/O image, when I/O completes, kernel must notify the user-level thread of the event via SA, and this notification requires a processor&lt;/li&gt;
&lt;li&gt;Application free to build any concurrency model on SAs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.scs.stanford.edu/06au-cs240/notes/l4d2.txt"&gt;Stanford 240 notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.ucr.edu/~heng/teaching/cs202-sp18/lec7.pdf"&gt;UC Riverside slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://courses.cs.vt.edu/cs5204/fall09-kafura/Presentations/Scheduler-Activations.pdf"&gt;Virginia Tech slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.utexas.edu/~rossbach/380L/lectures/14-Scheduler-Activations.pdf"&gt;UT380L slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Jitsu: Just-In-Time Summoning of Unikernels"</title><link href="https://zhu45.org/posts/2019/Mar/13/jitsu-just-in-time-summoning-of-unikernels/" rel="alternate"></link><published>2019-03-13T21:20:00+08:00</published><updated>2019-03-13T21:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-13:/posts/2019/Mar/13/jitsu-just-in-time-summoning-of-unikernels/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to build a system that is able to securely manage multi-tenant networked applications on embedded infrastructure?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High density/scalability&lt;/li&gt;
&lt;li&gt;Fast boot&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;VM-level isolation&lt;/li&gt;
&lt;li&gt;“Embedded cloud”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OS are traditionally designed to run on a wide range of hardware, and support a variety …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to build a system that is able to securely manage multi-tenant networked applications on embedded infrastructure?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High density/scalability&lt;/li&gt;
&lt;li&gt;Fast boot&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;VM-level isolation&lt;/li&gt;
&lt;li&gt;“Embedded cloud”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;OS are traditionally designed to run on a wide range of hardware, and support a variety of applications. But no longer true!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hypervisors in the cloud provides virtual hardware abstractions&lt;/li&gt;
&lt;li&gt;Many modern applications are single purpose microservices&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Container:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Think of as a lightweight VM&lt;/li&gt;
&lt;li&gt;Separate process space, network interface&lt;/li&gt;
&lt;li&gt;Setuid/root access possible&lt;/li&gt;
&lt;li&gt;Share kernel with host (thus, no I/O emulation, VM overheads)&lt;/li&gt;
&lt;li&gt;chroot, cgroups&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Achieves much of VM charter&lt;/li&gt;
&lt;li&gt;Separation of concerns: Dev (inside container), Ops (outside)&lt;/li&gt;
&lt;li&gt;Lightweight, good deployment unit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Limited compatibility&lt;/li&gt;
&lt;li&gt;Limited isolation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Container vs. VM:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="container vs. VM" class="img-responsive" src="https://zhu45.org/images/container-vm.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Problem with layers in existing solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complex configuration management&lt;/li&gt;
&lt;li&gt;Duplication leads to inefficiency&lt;/li&gt;
&lt;li&gt;Image size leads to long boot time&lt;/li&gt;
&lt;li&gt;All the layer leads to large attack surface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="container-drawbridge" class="img-responsive" src="https://zhu45.org/images/container-drawbridge.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Unikernels&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lightweight (fast, IoT-amenable)&lt;/li&gt;
&lt;li&gt;High consolidation ratios&lt;/li&gt;
&lt;li&gt;Small attack surface&lt;/li&gt;
&lt;li&gt;Type safety (safety in general)&lt;/li&gt;
&lt;li&gt;Minimize multi-RM pathologies&lt;/li&gt;
&lt;li&gt;Small binaries (host in git)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Increased pressure on (cloud) scheduler&lt;/li&gt;
&lt;li&gt;Threading&lt;/li&gt;
&lt;li&gt;Cross-domain communication&lt;/li&gt;
&lt;li&gt;Compatibility&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mirage Unikernel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS is a collection of modules (libs) with types (API)&lt;/li&gt;
&lt;li&gt;Written in OCaml&lt;/li&gt;
&lt;li&gt;Compact enough to boot/respond to network traffic in real-time&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Jitsu: Unikernels on demand&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Capture system dependencies in code/compile them away&lt;/li&gt;
&lt;li&gt;Swap system libraries to target different platforms&lt;/li&gt;
&lt;li&gt;Dev/Test on UNIX, deploy specializes to Xen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="unikernels" class="img-responsive" src="https://zhu45.org/images/unikernel-jitsu.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jitsu Architecture:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="jitsu-architecture" class="img-responsive" src="https://zhu45.org/images/jitsu-architecture.png"/&gt;&lt;/p&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Rethinking the Library OS from the Top Down"</title><link href="https://zhu45.org/posts/2019/Mar/13/rethinking-the-library-os-from-the-top-down/" rel="alternate"></link><published>2019-03-13T20:20:00+08:00</published><updated>2019-03-13T20:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-13:/posts/2019/Mar/13/rethinking-the-library-os-from-the-top-down/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we refactor a commerical OS to follow libOS architecture and achieve a better performance than VMM approach?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Three categories of services in OS implementations:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="three categories of services" class="img-responsive" src="https://zhu45.org/images/drawbridge-three-services.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why does a guest OS need a kernel? Because the host interface is virtual hardware&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="typical VMM" class="img-responsive" src="https://zhu45.org/images/drawbridge-question.png"/&gt;&lt;/p&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Goals …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we refactor a commerical OS to follow libOS architecture and achieve a better performance than VMM approach?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Three categories of services in OS implementations:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="three categories of services" class="img-responsive" src="https://zhu45.org/images/drawbridge-three-services.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why does a guest OS need a kernel? Because the host interface is virtual hardware&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="typical VMM" class="img-responsive" src="https://zhu45.org/images/drawbridge-question.png"/&gt;&lt;/p&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compatibility: Runs applications you use&lt;/li&gt;
&lt;li&gt;Lightweight: &amp;lt;1% of Windows library code&lt;/li&gt;
&lt;li&gt;Performance: 10x to 20x lower overheads than a VM&lt;/li&gt;
&lt;li&gt;Security: Secure isolation comparable to VM&lt;/li&gt;
&lt;li&gt;Mobility: Migrate running applications&lt;/li&gt;
&lt;li&gt;Generality: Independent evolution of host OS&lt;/li&gt;
&lt;li&gt;Manageability: Smaller “servicing” area&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hypothesis: it’s possible to design a software ABI with the same properties as hardware ABI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clearly specified, clean separation of concerns (No undocumented dependencies)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Minimally stateful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Registers, etc. are visible to guest OS/application&lt;/li&gt;
&lt;li&gt;State can be programmatically recreated&lt;/li&gt;
&lt;li&gt;Analogous to a stateless network protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Guest/Host ABI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Private virtual memory&lt;/li&gt;
&lt;li&gt;Threads, synchronization&lt;/li&gt;
&lt;li&gt;I/O streams&lt;/li&gt;
&lt;li&gt;Thread/process exit&lt;/li&gt;
&lt;li&gt;Time, random bits, handle reference management, checkpoint/restore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Refactoring the Desktop:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Host OS manages hardware&lt;/li&gt;
&lt;li&gt;Application services in library&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Desktop manager&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trusted host process&lt;/li&gt;
&lt;li&gt;Remote Desktop protocol&lt;/li&gt;
&lt;li&gt;Stateless&lt;/li&gt;
&lt;li&gt;Shell can be remote&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="refactoring the desktop" class="img-responsive" src="https://zhu45.org/images/drawbridge-refactor-desktop.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Drawbridge Architecture:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Drawbridge Architecture" class="img-responsive" src="https://zhu45.org/images/drawbridge-architecture.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Drawbridge Architecture 02" class="img-responsive" src="https://zhu45.org/images/drawbridge-architecture-02.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Incomplete port of windows API&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Printer support&lt;/li&gt;
&lt;li&gt;Accelerated graphics&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Support for multi-process applications (e.g., Outlook with Word as an editor, sharing state through windows subsystem)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Administrative tools will not work by design&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need more low-level system access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;End results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Refactored Windows 7 as a Library OS (80MB)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Functional benefits of VMs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Robust to changes in host system software&lt;/li&gt;
&lt;li&gt;Security isolation&lt;/li&gt;
&lt;li&gt;Migration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Drastically better scalability&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Run rich desktop applications&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Arrakis: The Operating System is the Control Plane"</title><link href="https://zhu45.org/posts/2019/Mar/13/arrakis-the-operating-system-is-the-control-plane/" rel="alternate"></link><published>2019-03-13T17:20:00+08:00</published><updated>2019-03-13T17:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-13:/posts/2019/Mar/13/arrakis-the-operating-system-is-the-control-plane/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design an OS for I/O intensive applications such that most I/O operations do not need kernel mediation?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The authors make a classic efficiency argument: servers usually perform conceptually simple operations, but in practice
this results in too much …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design an OS for I/O intensive applications such that most I/O operations do not need kernel mediation?&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The authors make a classic efficiency argument: servers usually perform conceptually simple operations, but in practice
this results in too much operating system overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The new secret sauce is that hardware device virtualization allows user-level programs to get efficient access to I/O
without compromising protection.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I/O centric design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bypass kernel&lt;/li&gt;
&lt;li&gt;Abstractions: user-space device access&lt;/li&gt;
&lt;li&gt;Single-Root I/O Virtualization (SR-IOV) is the hardware secret sauce. It allows software to setup flexible hardware
multiplexing. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kernel functionality re-divide in Arrakis:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="arrakis kernel functionality" class="img-responsive" src="https://zhu45.org/images/arrakis-kernel-functionality.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Architecture:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="arrakis architecture" class="img-responsive" src="https://zhu45.org/images/arrakis-architecture-01.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="arrakis architecture 02" class="img-responsive" src="https://zhu45.org/images/arrakis-architecture-02.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Hardware Model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NICs (Multiplexing, Protection, Scheduling)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Storage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VSIC (Virtual Storage Interface Controller): each with queues, etc&lt;/li&gt;
&lt;li&gt;VSA (Virtual Storage Areas): mapped to physical devices; associated with VSICs; VSA &amp;amp; VSIC: many-to-many mapping&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Control Plane Interface:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VIC (Virtual Interface Card): Apps can create/delete VICs, associate them to doorbells&lt;/li&gt;
&lt;li&gt;doorbells associated with events on VICs&lt;/li&gt;
&lt;li&gt;filter creation (e.g., &lt;code&gt;create_filter(rx,*,tcp.port == 80)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Access control: enforced by filters; infrequentily invoked (during setup, etc)&lt;/li&gt;
&lt;li&gt;Resource limiting: send commands to hardware I/O schedulers&lt;/li&gt;
&lt;li&gt;Naming: VFS in kernel; actual storage implemented in apps&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Network Data Interface:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apps send/receive directly through sets of queues&lt;/li&gt;
&lt;li&gt;Filters applied for multiplexing&lt;/li&gt;
&lt;li&gt;Doorbell used for asynchronous notification (e.g., packet arrival)&lt;/li&gt;
&lt;li&gt;Both native (w/ zero-copy) and POSIX are implemented&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Storage Data Interface:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VSA supports read, write, flush&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;persistent data structure (log, queue)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;operations immediately persistent on disk&lt;/li&gt;
&lt;li&gt;eliminate marshaling (layout in memory = in disk)&lt;/li&gt;
&lt;li&gt;data structure specific caching &amp;amp; early allocation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This paper exploits the wide variety of hardware. Some of them do not even exist or are quite limited (e.g., VSIC support). 
Personally, I’m not a huge fun of this type of research as the main goal seems to be “let’s delegate OS work to the hardware”.
But, it indeed lays out a vision that what OS can be if hardware is powerful enough and the applications on top of OS are not
quite complex and do not need much kernel involvement (e.g., scheduling).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The presentation of motivation through rigorous measurement (Table 1 and Table 2) is something I really enjoy. In addition, the detailed analysis of the overhead involving kernel (Background section) has much useful information to further study for myself.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros: much better raw performance (for I/O intensive Data Center apps)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Redis: up to 9x throughput and 81% speedup&lt;/li&gt;
&lt;li&gt;Memcached: scales up to 3x throughput&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some features require hardware functionality that is not yet available&lt;/li&gt;
&lt;li&gt;require modification of applications&lt;/li&gt;
&lt;li&gt;not clear about storage abstractions&lt;/li&gt;
&lt;li&gt;not easy to track behaviors inside the hardware&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Memory Resource Management in VMware ESX Server"</title><link href="https://zhu45.org/posts/2019/Mar/11/memory-resource-management-in-vmware-esx-server/" rel="alternate"></link><published>2019-03-11T23:24:00+08:00</published><updated>2019-03-11T23:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-11:/posts/2019/Mar/11/memory-resource-management-in-vmware-esx-server/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#ballooning"&gt;Ballooning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#content-based-page-sharing"&gt;Content-based Page Sharing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#managing-memory-with-taxes"&gt;Managing Memory with Taxes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#others"&gt;Others&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a memory management system inside VMM to manage memory allocated to each guest OS (i.e., VM)? This is challenging
as each guest OS also has its own resource manager and how …&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#ballooning"&gt;Ballooning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#content-based-page-sharing"&gt;Content-based Page Sharing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#managing-memory-with-taxes"&gt;Managing Memory with Taxes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#others"&gt;Others&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a memory management system inside VMM to manage memory allocated to each guest OS (i.e., VM)? This is challenging
as each guest OS also has its own resource manager and how to ensure performance isolation across all VMs.&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;VMWare ESX Server runs on bare hardware (compared with VMM runs on a control OS like KVM); In “control OS” approach, here is the workflow of reading a file from an application in VM:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;an application read from a file (in VM)&lt;/li&gt;
&lt;li&gt;OS translates request into a read from block device (in VM)&lt;/li&gt;
&lt;li&gt;VMM translates that to a read from a file from host OS (in VMM)&lt;/li&gt;
&lt;li&gt;host OS translates request to a read from the machine’s block device (in control OS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Problems with previous memory management approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VMM page replacement algorithm can pick a page important to guest OS. Causes performance anomalies.&lt;/li&gt;
&lt;li&gt;Double paging problem: If VMM pages out first, OS page out the same page will cause VMM fault in the same page from system
paging device just to write out to the virtual paging device.&lt;/li&gt;
&lt;li&gt;Constraint: OS does not have a facility for changing amount of physical memory at runtime&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;machine address: actual hardware memory&lt;/li&gt;
&lt;li&gt;“physical” address: software abstraction used to provide illusion of hardware memory to a virtual machine&lt;/li&gt;
&lt;li&gt;shadow page table: virtual-to-machine page mappings&lt;/li&gt;
&lt;li&gt;overcommitment: the total size configured for all running virtual machines exceeds the total amount of actual machine memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ballooning"&gt;Ballooning&lt;/h3&gt;
&lt;p&gt;Force guest OS to use its own page replacement algorithm&lt;/p&gt;
&lt;p&gt;&lt;img alt="ballooning" class="img-responsive" src="https://zhu45.org/images/ballooning.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Download VMWare balloon module into guest OS as a pseudo-device driver or kernel service&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;no external interface within the guest&lt;/li&gt;
&lt;li&gt;communicate with ESX server via a private channel&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If ESX wants to reclaim memory, it instructs the driver to “inflate” by allocating pinned physical pages within VM and the memory pressure in guest OS force the guest OS to free memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pinned physical pages used by balloon are told to ESX so that ESX can reclaim corresponding machine pages
  (i.e., pages allocated to balloon have their entry in the &lt;code&gt;pmap&lt;/code&gt; marked, can be reclaimed by VMM)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Defalte balloon to get OS to use more memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If guest touches a balloon page, allocate a new page (machine page stealed from guest OS has to be returned)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Might not be able to reclaim memory fast enough&lt;/li&gt;
&lt;li&gt;Guest OS might refuse memory allocation request or limit the driver’s ability to allocate memory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Can always resort to paging. Using randomize algorithm to avoid pathologically bad cases of paging out exactly what guest OS needs&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="content-based-page-sharing"&gt;Content-based Page Sharing&lt;/h3&gt;
&lt;p&gt;Able to share a page without modification to guest OS (compared to Disco’s approach)&lt;/p&gt;
&lt;p&gt;&lt;img alt="content-based page sharing" class="img-responsive" src="https://zhu45.org/images/esx-content-sharing.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hash every page, store hashes in a hash table&lt;/li&gt;
&lt;li&gt;On collision, check if pages are identical. If they are, share copy-on-write&lt;/li&gt;
&lt;li&gt;With no collision, store hash as hint. On future collision check if hint is still valid (page content have not changed). If
it is, share page.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="managing-memory-with-taxes"&gt;Managing Memory with Taxes&lt;/h3&gt;
&lt;p&gt;The problem with proportional share allocators is that they let rich clients hoard resources. VMWare adds a tax to idle memory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The basic idea is to charge a client more for an idle page than for one it is actively using&lt;/li&gt;
&lt;li&gt;Tax rate specifies the maximum fraction of idle pages that may be reclaimed from a client&lt;/li&gt;
&lt;li&gt;Inflate cost of idle memory by tax rate&lt;/li&gt;
&lt;li&gt;Allow 25% idle memory to provide a buffer for a fast-growing working set increase&lt;/li&gt;
&lt;li&gt;Only need percentage of idle memory: measure by random sampling&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="others"&gt;Others&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Actions to reclaim memory when percentage of free memory hits certain level:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;high (6%): no reclamation&lt;/li&gt;
&lt;li&gt;soft (4%): balloon, page when nencessary (share before swap)&lt;/li&gt;
&lt;li&gt;hard (2%): page&lt;/li&gt;
&lt;li&gt;low (1%): suspend VM&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I/O Page remapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;overcommitment may lead to problem that guest OS may address machine page that doesn’t exist (e.g., DMA on 32-bit access pages above 4GB boundary (“high” memory))&lt;/li&gt;
&lt;li&gt;fix: keep track of “hotness” of pages in high memory and when the I/O refernce count of such pages exceed certain threshold,
they are remapped to low memory. May remap low memory pages to high memory pages to get more space for “hotness” remapping&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Another well-written paper. Each technique is explained very clearly. Its writing style is quite unique as well: evaluation
is divided and associated with relvant technique introduced. I personally like this style better as it gives me some break between
each major point.&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Xen and the Art of Virtualization"</title><link href="https://zhu45.org/posts/2019/Mar/11/xen-and-the-art-of-virtualization/" rel="alternate"></link><published>2019-03-11T23:13:00+08:00</published><updated>2019-03-11T23:13:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-11:/posts/2019/Mar/11/xen-and-the-art-of-virtualization/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Provide a high performance resource-managed virtual machine monitor (VMM) that provides performance guarantees to concurrent
execution of multiple operating systems: “hosting up to 100 virtual machine in- stances simultaneously on a modern server”&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Big picture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="OSes, VMs, Containers" class="img-responsive" src="https://zhu45.org/images/OSes-VMs-Containers.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two types of VMMs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="VMM types" class="img-responsive" src="https://zhu45.org/images/VMM-types.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Virtualization techniques &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1 …&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Provide a high performance resource-managed virtual machine monitor (VMM) that provides performance guarantees to concurrent
execution of multiple operating systems: “hosting up to 100 virtual machine in- stances simultaneously on a modern server”&lt;/p&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Big picture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="OSes, VMs, Containers" class="img-responsive" src="https://zhu45.org/images/OSes-VMs-Containers.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Two types of VMMs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="VMM types" class="img-responsive" src="https://zhu45.org/images/VMM-types.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Virtualization techniques &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Popek_and_Goldberg_virtualization_requirements"&gt;Fidelity&lt;/a&gt;: A program running under the VMM should exhibit a behavior essentially identical to that demonstrated when running on an equivalent machine directly.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.utdallas.edu/~zxl111930/spring2012/public/lec19-handout.pdf"&gt;Interposition&lt;/a&gt;: All guests actions go through monitor; monitor can inspect, modify, deny operations (e.g., compression, encryption, profiling, translation)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="VMM virtualization" class="img-responsive" src="https://zhu45.org/images/virtualization-techniques.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Full virtualization is slow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VMWare’s ESX Server dynamically rewrites portions of the hosted machine code to insert traps whenever VMM intervention
might be required. This applies to entire guest OS as all non-trapping privileged instructions must be caught and handled.&lt;/li&gt;
&lt;li&gt;ESX Server maintains shadow page table and to maintain consistency with virtual tables, it traps every update.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System Design&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Xen architecture" class="img-responsive" src="https://zhu45.org/images/xen-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Paravirtualization: idealized machine, efficient to virtualize&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More efficient than “full” virtualization&lt;/li&gt;
&lt;li&gt;Cost: need to modify OS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For safety: Xen exists in a 64MB section at the top of every address space, thus avoiding a TLB flush when entering and leaving 
hypervisor&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CPU:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;X86 supports 4 privilege levels: Without Xen, 0 for OS, and 3 for applications; Xen downgrades OS to level 1, and it runs 
level 0&lt;/li&gt;
&lt;li&gt;Syscall and page-fault handlers: registered to Xen; “fast handlers” most exceptions, don’t invole Xen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Paravirtualization techniques:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run VMM at ring 0, OS at ring 1 (app stays at ring 3)&lt;/li&gt;
&lt;li&gt;System calls vector directly to guest OS without VMM involvement. Validate handler at install time.&lt;/li&gt;
&lt;li&gt;Page fault handler doesn’t read &lt;code&gt;cr2&lt;/code&gt; to get faulting address, put it in stack frame. VMM must execute to read &lt;code&gt;cr2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Mappings validated when page tables written (same as exokernel)&lt;/li&gt;
&lt;li&gt;Updates to page table are batched and validated in bulk. Avoiding interrupt-like updates is an important technique.&lt;/li&gt;
&lt;li&gt;Type and reference count for each physical frame (PD, PT, LDT, GDT, RW)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hardware physical to machine memory mapping readable by all VMs. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Needed by guest OS for writing page table, and useful for superpages or cache coloring.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;VMs have access to both real and virtual time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;All devices use shared-memory asynchronus buffer-descriptor rings (a batch interface)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Interrupts replaced with event delivery bitmap. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Events can be held off like disabling interrupts.&lt;/li&gt;
&lt;li&gt;Some control over notification granularity, allowing latency/bandwidth tradeoffs (e.g., notify for every packet,
or every 16 packets)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I/O requests have a unique ID and can be reordered&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;E.g., Guest OS and Xen can schedule the disk arm&lt;/li&gt;
&lt;li&gt;But guest can pass a reorder barrier to prevent some reordering (e.g., for file system consistency)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OS makes hypercalls to VMM (e.g., install page table entries)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Other important ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Domains are virtual machines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Domain 0 provides the administrative functions of the VMM (keeps complexity out of the VMM proper)&lt;/li&gt;
&lt;li&gt;Domain 0 contains the real device drivers (domain 0 is the target of malware attacks)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Virtual network devices (VIFs) may filter packets to prevent spoofing&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Memory is paritioned across domains. A domain provides memory for I/O operations. 1 page per packet (wow).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="further-reading"&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://courses.cs.vt.edu/cs5204/fall14-butt/lectures/xen.pdf"&gt;Xen and The Art of Virtualization VT slide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.slideshare.net/susheel2658/xen-and-the-art-of-virtualization-28187840"&gt;Another slide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dsc.soic.indiana.edu/publications/virtualization.pdf"&gt;A write-up on understanding some fundamental virtualization techniques&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/21462581/what-is-the-difference-between-full-para-and-hardware-assisted-virtualization"&gt;SO post on difference between Full virtualization and Paravirtualization&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Practical, transparent operating system support for superpages"</title><link href="https://zhu45.org/posts/2019/Mar/10/practical-transparent-operating-system-support-for-superpages/" rel="alternate"></link><published>2019-03-10T15:00:00+08:00</published><updated>2019-03-10T15:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-10:/posts/2019/Mar/10/practical-transparent-operating-system-support-for-superpages/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#superpage-definition-and-benefits"&gt;Superpage definition and benefits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#superpage-issues"&gt;Superpage issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System Designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#allocation"&gt;Allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#incremental-promotion"&gt;Incremental Promotion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#demotions"&gt;Demotions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fragmentation-control"&gt;Fragmentation Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#auxiliary-data-structure-population-map"&gt;Auxiliary data structure: population map&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a general and transparent superpage management system to achieve high and sustained performance for real workloads
and negligible degradation in pathological situations?&lt;/p&gt;
&lt;h2 id="superpage-definition-and-benefits"&gt;Superpage definition and …&lt;/h2&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#superpage-definition-and-benefits"&gt;Superpage definition and benefits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#superpage-issues"&gt;Superpage issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System Designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#allocation"&gt;Allocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#incremental-promotion"&gt;Incremental Promotion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#demotions"&gt;Demotions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fragmentation-control"&gt;Fragmentation Control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#auxiliary-data-structure-population-map"&gt;Auxiliary data structure: population map&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a general and transparent superpage management system to achieve high and sustained performance for real workloads
and negligible degradation in pathological situations?&lt;/p&gt;
&lt;h2 id="superpage-definition-and-benefits"&gt;Superpage definition and benefits&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Superpage definition:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memory pages of larger sizes (e.g., 8KB, 64KB, 512KB, 4MB)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The rest is the same as the normal pages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;power of 2 size&lt;/li&gt;
&lt;li&gt;use only one TLB entry&lt;/li&gt;
&lt;li&gt;contiguous&lt;/li&gt;
&lt;li&gt;aligned (physically and virtually)&lt;/li&gt;
&lt;li&gt;uniform protection attributes&lt;/li&gt;
&lt;li&gt;one reference bit, one dirty bit&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Superpage improves TLB coverage (i.e., the amount of memory accessible through cached mappings. In other words, without incurrin misses in the TLB)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="superpage-issues"&gt;Superpage issues&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Allocation: how/when/what size to allocate?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="superpage allocation issue" class="img-responsive" src="https://zhu45.org/images/superpage-allocation.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Promotion (create a superpage out of a set of smaller pages)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wait for app to touch pages (the gray ones) may lose opportunities to increase TLB coverage&lt;/li&gt;
&lt;li&gt;Create small superpage (the first four blue ones) may waste overhead&lt;/li&gt;
&lt;li&gt;Forcibly populate pages (i.e., group all eight base pages into one superpage) may lead to internal fragmentation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="superpage promotion issue" class="img-responsive" src="https://zhu45.org/images/superpage-promotion.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Demotion (convert a superpage into smaller pages). Happens when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;page attributes of base pages of a superpage become non-uniform (e.g., some of the base pages protection
attributes changed and different from the rest within the superpage)&lt;/li&gt;
&lt;li&gt;during partial pageouts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fragmentation &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Memory becomes fragmentated due to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;use of multiple page sizes&lt;/li&gt;
&lt;li&gt;persistence of file cache pages&lt;/li&gt;
&lt;li&gt;scattered wired (non-pageable) pages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Continuity: contended resource&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS must trade off impact of contiguity restoration against superpage benefits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-designs"&gt;System Designs&lt;/h2&gt;
&lt;h3 id="allocation"&gt;Allocation&lt;/h3&gt;
&lt;p&gt;&lt;img alt="superpage rervation allocation" class="img-responsive" src="https://zhu45.org/images/superpage-reservation-allocation.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Determines a preferred superpage size for the region encompassing the base page whose access caused the page fault&lt;/li&gt;
&lt;li&gt;The entire set of frames (gray ones above) is tentatively reserved for potential future use as a superpage, and added to a 
reservation list.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reservation size: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;memory objects fixed in size (e.g., code, file): largest, aligned superpage (contains the faulting page) + doesn’t overlap with existing reservations or allocated pages + no larger than object&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;memory objects with dynamic size (e.g., heap): everything same as above except not restricting no larger than object&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;If size is not available, preempt existing reservation or resign to a smaller size&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;preemption policy: the reservation is preempted whose most recent page allocation occured least recently, among all candidate reservations.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use reservation list: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keep track of reserved page frame extents that are not fully-populated&lt;/li&gt;
&lt;li&gt;One reservation list for each page size supported by the hardware except for the largest superpage size&lt;/li&gt;
&lt;li&gt;Reservation in each list are kept sorted by the time of their most recent page frame allocations. When the system decides to preempt a reservation of a given size, it chooses the reservation at the head of the list for that size.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="incremental-promotion"&gt;Incremental Promotion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Promote only regions that are fully populated by the application&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Promotion occurs to the smallest superpage size as soon as the population count corresponds to that size. Then, when the population count reaches the enxt larger superpage size, another promotion occurs to the next size, and so on.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="superpage incremental promotion" class="img-responsive" src="https://zhu45.org/images/superpage-incremental-promotion.png"/&gt;&lt;/p&gt;
&lt;h3 id="demotions"&gt;Demotions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Speculative demotions: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One reference bit per superpage: how do we detect portions of a superpage not referenced anymore?&lt;/li&gt;
&lt;li&gt;Solution: On memory pressure, demote superpages when resetting reference bit; Re-promote (incrementally) as pages are referenced&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="superpage speculative demotions" class="img-responsive" src="https://zhu45.org/images/superpage-speculative-demotion.png"/&gt;&lt;/p&gt;
&lt;h3 id="fragmentation-control"&gt;Fragmentation Control&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Low contiguity: modified page daemon&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;restore contiguity: move clean, inactive pages to the free list&lt;/li&gt;
&lt;li&gt;minimize impact: prefer pages that contribute the most to contiguity; keep contents for as long as possible (even when part of a reservation: if reactivated, break reservation)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cluster wired pages&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="auxiliary-data-structure-population-map"&gt;Auxiliary data structure: population map&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Population maps keep track of allocated base pages within each memory object.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Purpose:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reserved frame lookup&lt;/li&gt;
&lt;li&gt;Overlap avoidance&lt;/li&gt;
&lt;li&gt;Promotion decisions&lt;/li&gt;
&lt;li&gt;Preemption assitance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implemented as a radix tree. Details see paper&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Another well-written paper. I think it is a good candidate for a self-learning project (i.e., implementing superpage management system on JOS)&lt;/li&gt;
&lt;/ul&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Threads and Input/Output in the Synthesis Kernel"</title><link href="https://zhu45.org/posts/2019/Mar/10/threads-and-inputoutput-in-the-synthesis-kernel/" rel="alternate"></link><published>2019-03-10T12:20:00+08:00</published><updated>2019-03-10T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-10:/posts/2019/Mar/10/threads-and-inputoutput-in-the-synthesis-kernel/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System Designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#dataflow-synthesis-model-of-computation"&gt;Dataflow: Synthesis Model of Computation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fast-context-switch-procedure-chaining"&gt;Fast context switch: procedure chaining&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mechanism-to-reduce-syncrhonization-overhead"&gt;Mechanism to reduce syncrhonization overhead&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design an OS for a parallel and distributed computational environment and achieve the following three goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High performance&lt;/li&gt;
&lt;li&gt;Self-tuning capability to dynamic load and configuration changes&lt;/li&gt;
&lt;li&gt;A simple, uniform and …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System Designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#dataflow-synthesis-model-of-computation"&gt;Dataflow: Synthesis Model of Computation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fast-context-switch-procedure-chaining"&gt;Fast context switch: procedure chaining&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mechanism-to-reduce-syncrhonization-overhead"&gt;Mechanism to reduce syncrhonization overhead&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design an OS for a parallel and distributed computational environment and achieve the following three goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High performance&lt;/li&gt;
&lt;li&gt;Self-tuning capability to dynamic load and configuration changes&lt;/li&gt;
&lt;li&gt;A simple, uniform and intuitive model of computation with a high-level interface&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-designs"&gt;System Designs&lt;/h2&gt;
&lt;h3 id="dataflow-synthesis-model-of-computation"&gt;Dataflow: Synthesis Model of Computation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The threads of execution form a directed graph, in which the nodes are threads and the arcs are data flow channels&lt;/li&gt;
&lt;li&gt;Observation: Data follows a pipeline connects many OS-managed devices/resources (e.g., &lt;code&gt;capture | xform | filter | detect &amp;amp;&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Dataflow example from Synthesis: FS" class="img-responsive" src="https://zhu45.org/images/dataflow-synthesis.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Above shows a dataflow example from Synthesis: file system server. It differs from a traditional design:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Boxes are threads/servers&lt;/li&gt;
&lt;li&gt;Boxes are connected directly with &lt;code&gt;jmp&lt;/code&gt; instructions to implement scheduling&lt;/li&gt;
&lt;li&gt;Arrows (and boxes) are specialized dynamically to the application&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fast-context-switch-procedure-chaining"&gt;Fast context switch: procedure chaining&lt;/h3&gt;
&lt;p&gt;&lt;img alt="procedure chaining" class="img-responsive" src="https://zhu45.org/images/procedure-chaining.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Picture above shows that the ready-to-run threads are chained in an executable circular queue. A &lt;code&gt;jmp&lt;/code&gt;
instruction in each context-switch-out procedure of the preceding thread points to the context-switch-in procedure of the 
follow thread.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;“Executable data structures”: embed code in data structures to avoid data 
structure traversals and to specialize code for each object (e.g., put context switch code inside of thread control block)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context switch steps: Timer interrup vectored directly to current thread’s &lt;code&gt;sw_out&lt;/code&gt;; &lt;code&gt;sw_out&lt;/code&gt; calls (directly) next thread’s 
&lt;code&gt;sw_in&lt;/code&gt; or &lt;code&gt;sw_in_mmu&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;interrupt vectored to &lt;code&gt;sw_out&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sw_out&lt;/code&gt; saves registers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sw_out&lt;/code&gt; jumps to next &lt;code&gt;sw_in_mmu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sw_in_mmu&lt;/code&gt; updates MMU&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sw_in_mmu&lt;/code&gt; updates CPU interrupt vector base&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sw_in_mmu&lt;/code&gt; restores CPU registers (including putting user-PC into the user-PC register)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sw_in_mmu&lt;/code&gt; does return from exception (replacing PC with user-PC and changing mode back to user mode)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mechanism-to-reduce-syncrhonization-overhead"&gt;Mechanism to reduce syncrhonization overhead&lt;/h3&gt;
&lt;p&gt;Lots of techniques used to reduce synchronization overhead&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Code Isolation: reduce false sharing (i.e., eliminate false sharing within a single C struct) (e.g., thread table entries (TTEs) are not shared. Similar to privatization)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Procedure Chaining: use continuations (implemented by changing the return address on the stack) to allow certain services to complete atomically (e.g., defer signal to end of interrupt handling)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optimistic synchronization: it is easier to break the rule and ask forgiveness than get permission. Try the operation, but before commit, check to see if no one else interfered.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lock-free queues that use the compare-and-swap instruction &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. This is not wait-free (some operations do not have bounded waiting time), it is obstruction-free (a thread, executed in isolation for a bounded number of operations will complete).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Even I cannot fully understand every bit details of the paper, I think it is the best written paper I have read so far 
in the semester (the flow is great).&lt;/li&gt;
&lt;li&gt;Many details in the paper are omit: scheduling, interrupt handling, details of lock-free queues (SP-SC, MP-MC,etc)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lots of cool techniques that are worth investigation in its own rights and they are “field openers”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Code synthesis (JIT compiler, super-optimizers)&lt;/li&gt;
&lt;li&gt;Code isolation (Privatization)&lt;/li&gt;
&lt;li&gt;Procedure chaining (Continuations (lambda, events))&lt;/li&gt;
&lt;li&gt;Optimistic synchronization (lock-free data structures)&lt;/li&gt;
&lt;li&gt;Synthesis I/O (Dataflow: Scout, Click Router, SEDA, StageServer, IXP, PTask, etc)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;See &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/threads-locks.pdf"&gt;OSTEP::locks&lt;/a&gt; for details on test-and-set and compare-and-swap instruction and their usage in lock implementations. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"END-TO-END ARGUMENTS IN SYSTEM DESIGN"</title><link href="https://zhu45.org/posts/2019/Mar/09/end-to-end-arguments-in-system-design/" rel="alternate"></link><published>2019-03-09T21:20:00+08:00</published><updated>2019-03-09T21:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-09:/posts/2019/Mar/09/end-to-end-arguments-in-system-design/</id><summary type="html">&lt;h2 id="main-point"&gt;Main Point&lt;/h2&gt;
&lt;p&gt;The following statements provide different angles of stating the same “end-to-end argument”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Functions placed at low levels of a system may be redundant or of little value when compared with the cost of providing them
at that low level; low level mechanisms to support these functions are justified …&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;h2 id="main-point"&gt;Main Point&lt;/h2&gt;
&lt;p&gt;The following statements provide different angles of stating the same “end-to-end argument”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Functions placed at low levels of a system may be redundant or of little value when compared with the cost of providing them
at that low level; low level mechanisms to support these functions are justified only as performance enhancments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since application knows its needs the most, it is natural for system to move function upward in a layered system, closer to the application that uses the function.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The function in question can completely and correctly be implemented only with the knowledge and help of the application standing at the end points of the communication system. Therefore, providing that questioned function as a feature of the communication system itself is not possible. (Sometimes an incomplete version of the function provided by the communication system may be useful as a performance enhancment.&lt;a href="https://en.wikipedia.org/wiki/Worse_is_better"&gt;“Worse is better”&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The end-to-end argument says that many functions in a communication system can only be completely and correctly implemented with the help of the application(s) at the endpoints &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="example-file-transfer"&gt;Example: File transfer&lt;/h2&gt;
&lt;p&gt;In the paper, a scenario about transferring file between host A and host B is used to demonstrate “end-to-end argument”.&lt;/p&gt;
&lt;p&gt;File transfer application still needs to compare checksum on receving host with the sending host to ensure the file consistency
and retransfer the file if the checksum differ even the underlying communication system has implemented similar mechanism to ensure no change bits in a packet or packet gets dropped. In other words, the file transfer application must provide its own retries based on an end-to-end checksum of the file. And if it does so, the extra effort expended in the communication system to provide a guarantee of reliable data transmission is only reducing the frequency of retries by the file transfer application; it has no effect on inevitablity or correctness of the outcome, since correct file transmission is assured by the end-to-end checksum and retry whether or not the data transmission system is reliable. Thus, the data communication system to go out of its way to be extraordinarily reliable does not reduce the burden on the application program to ensure reliability.&lt;/p&gt;
&lt;p&gt;Thus, low levels need not provide “perfect” reliability (e.g., communication system in this example) as the upper application still needs to implement the same functionality again to ensure correctness. However, communication system still needs to implement some mechanism to improve application performance (e.g., reduce application retries in this case). However, the point is that such mechanism needs not to be “perfect” (e.g., strive for a negligible error rate so that retries never happens). In addition, lower levels may not have enough information to “perfect” functions used by applications and the overhead introduced by such functions tax on the applications that are on the same system but never need such functionality.&lt;/p&gt;
&lt;p&gt;More examples are discussed in paper: (application level) encryption, duplicate message detection, message sequencing, guaranteed message delivery, detection of crashes, and delivery receipts.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;From &lt;a href="https://blog.acolyer.org/2014/11/14/end-to-end-arguments-in-system-design/"&gt;morning paper&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>"Exokernel: An Operating System Architecture for Application-Level Resource Management"</title><link href="https://zhu45.org/posts/2019/Mar/09/exokernel-an-operating-system-architecture-for-application-level-resource-management/" rel="alternate"></link><published>2019-03-09T13:20:00+08:00</published><updated>2019-03-09T13:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-09:/posts/2019/Mar/09/exokernel-an-operating-system-architecture-for-application-level-resource-management/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#approach"&gt;Approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background-extensibility"&gt;Background: extensibility&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#os-per-application"&gt;OS per application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#microkernels"&gt;Microkernels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#virtual-machines"&gt;Virtual machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#download-untrusted-code-into-kernel"&gt;Download untrusted code into kernel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#high-level-architecture"&gt;High-level Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#exokernel-principles"&gt;Exokernel principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#key-mechanisms"&gt;Key Mechanisms&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#secure-bindings"&gt;Secure bindings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#visible-revocation"&gt;Visible revocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#abort-protocol"&gt;Abort protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#capabilities"&gt;Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#others"&gt;Others&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#specific-abstractions"&gt;Specific Abstractions&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#network"&gt;Network&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#multiplexing-the-network-packet-filter"&gt;Multiplexing the network: packet filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#application-specific-safe-handlers-ash"&gt;Application-specific safe handlers (ASH)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design an OS …&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#approach"&gt;Approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background-extensibility"&gt;Background: extensibility&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#os-per-application"&gt;OS per application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#microkernels"&gt;Microkernels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#virtual-machines"&gt;Virtual machines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#download-untrusted-code-into-kernel"&gt;Download untrusted code into kernel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#high-level-architecture"&gt;High-level Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#exokernel-principles"&gt;Exokernel principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#key-mechanisms"&gt;Key Mechanisms&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#secure-bindings"&gt;Secure bindings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#visible-revocation"&gt;Visible revocation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#abort-protocol"&gt;Abort protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#capabilities"&gt;Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#others"&gt;Others&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#specific-abstractions"&gt;Specific Abstractions&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#network"&gt;Network&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#multiplexing-the-network-packet-filter"&gt;Multiplexing the network: packet filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#application-specific-safe-handlers-ash"&gt;Application-specific safe handlers (ASH)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How can we design an OS such that it improves performance of standard applications while providing flexibility to enable applications to customize 
resource management to improve performance?&lt;/p&gt;
&lt;h2 id="approach"&gt;Approach&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;extensibility: application knows best what resource mangement it needs. Therefore, it should make decisions whenever possible (end-to-end argument)&lt;/li&gt;
&lt;li&gt;minimalist: kernel’s job is to protect resources, not to manage them (“separate protection from resource management”)&lt;/li&gt;
&lt;li&gt;challenge: identify core of the abstractions for different resources&lt;/li&gt;
&lt;li&gt;Thin kernel, fat OS libraries&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="background-extensibility"&gt;Background: extensibility&lt;/h2&gt;
&lt;p&gt;There are five approaches to extensibility (including Exokernel):&lt;/p&gt;
&lt;h3 id="os-per-application"&gt;OS per application&lt;/h3&gt;
&lt;p&gt;&lt;img alt="os per application" class="img-responsive" src="https://zhu45.org/images/os-per-application.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example: &lt;a href="http://www.cs.utah.edu/flux/fluke/html/"&gt;Fluke&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Idea:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hypervisor provides resource management and isolation&lt;/li&gt;
&lt;li&gt;Additional guest-OS layers redundant and unnecessary&lt;/li&gt;
&lt;li&gt;Collapse guest OS and application into same domain (typically compiles OS and app into the same binary)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast (same advantage provides by &lt;a href="https://en.wikipedia.org/wiki/Unikernel"&gt;Unikernel&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Co-existence applications&lt;/li&gt;
&lt;li&gt;Kernels are fragile and hard to modify&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="microkernels"&gt;Microkernels&lt;/h3&gt;
&lt;p&gt;&lt;img alt="microkernels" class="img-responsive" src="https://zhu45.org/images/microkernels.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Examples: &lt;a href="https://homes.cs.washington.edu/~levy/capabook/Chapter6.pdf"&gt;Hydra&lt;/a&gt;, &lt;a href="https://www.os-book.com/OS9/appendices-dir/b.pdf"&gt;Mach&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Idea:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal OS core to manage hardware&lt;/li&gt;
&lt;li&gt;Higher level abstractions in user space&lt;/li&gt;
&lt;li&gt;IPC fundamental cross-domain primitive&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fault isolation&lt;/li&gt;
&lt;li&gt;Better extensibility&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slow (kernel crossings)&lt;/li&gt;
&lt;li&gt;Limited extensibility (maky make it easeir for OS developer to extend, but not user)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="virtual-machines"&gt;Virtual machines&lt;/h3&gt;
&lt;p&gt;&lt;img alt="VM" class="img-responsive" src="https://zhu45.org/images/VM.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Examples: VM370, Disco, VMware, &lt;a href="https://www.cl.cam.ac.uk/research/srg/netos/papers/2003-xensosp.pdf"&gt;Xen&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Different apps need different OSes&lt;/li&gt;
&lt;li&gt;Figure our how to run more than one OS at a time&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;low-level interface (“ideal” according to Exokernel standard)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“emulate” machine vs. “export” resources (e.g., need to emulate “privileged” instructions)&lt;/li&gt;
&lt;li&gt;Poor IPC (traditionally): machines isolated&lt;/li&gt;
&lt;li&gt;Hide resource management&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="download-untrusted-code-into-kernel"&gt;Download untrusted code into kernel&lt;/h3&gt;
&lt;p&gt;&lt;img alt="download untrusted code into kernel" class="img-responsive" src="https://zhu45.org/images/donwload-untrusted-code-into-kernel.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Examples: &lt;a href="https://cseweb.ucsd.edu/~savage/papers/Sosp95.pdf"&gt;Spin&lt;/a&gt;, &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.9071&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;Vino&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ideas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS provides extensibility interfaces&lt;/li&gt;
&lt;li&gt;Apps provide extensions that execute in kernel mode&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;extension&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Still working with same OS structure&lt;/li&gt;
&lt;li&gt;Only extensible within limits of extensbility API&lt;/li&gt;
&lt;li&gt;New thicket of isolation and trust issues&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-designs"&gt;System designs&lt;/h2&gt;
&lt;h3 id="high-level-architecture"&gt;High-level Architecture&lt;/h3&gt;
&lt;p&gt;Like previous four types of system, exokernel is another system architecture style focusing on the system extensibility.&lt;/p&gt;
&lt;p&gt;&lt;img alt="exokernel" class="img-responsive" src="https://zhu45.org/images/exokernel.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="exokernel architecture" class="img-responsive" src="https://zhu45.org/images/exokernel-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Top level structure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A small monolithic kernel&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;low-level, fixed interface&lt;/li&gt;
&lt;li&gt;Ideally hardware interface&lt;/li&gt;
&lt;li&gt;few and simple abstractions&lt;/li&gt;
&lt;li&gt;extension types: resource state data (page table entries), specialized resource management modules&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Libraries of untrusted resource management routines&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VM replacement&lt;/li&gt;
&lt;li&gt;File System&lt;/li&gt;
&lt;li&gt;IPC&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Libraries are part of OS. Historically, OS was set of libraries for math, etc. However, it is not true today.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Key difference - trust: application can write over library, jump to bad address in library, etc. Thus, kernel cannot trust library.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exokernel borrows liberally from other approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Like Fluke: make it easy for each app to have custom OS&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Like virtual machine: exokernel exports virtual machine but different in&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Transparency: traditional VM wants to run unmodified OS’s; exokernel VM wants to support custom OS’s&lt;/li&gt;
&lt;li&gt;Export rather than emulate resource: libOS is aware of multiplexing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Like Vino, Spin: one mechanism for extensibility is to download untrusted code into kernel&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Philosophy&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Traditional OS = protection + abstraction&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exokernel:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Protection = kernel (minimal mechanism) + library (resource sharing policy)&lt;/li&gt;
&lt;li&gt;Abstraction = library&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="exokernel-principles"&gt;Exokernel principles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Separate protection and management&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;export resources at lowest level possible with protection (e.g., disk blocks, TLB entries, etc)&lt;/li&gt;
&lt;li&gt;resource management only at level needed for protection (e.g., allocation, revocation, sharing, tracking of ownership)&lt;/li&gt;
&lt;li&gt;“abstraction (mechanism) is policy”: the implementation of abstractions in library operating systems can be simpler and 
  more specialized than in-kernel implementations, because library operating systems need not multiplex a resource 
  among competing applications with widely different demands&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Expose allocation: allocations allocate resources explicitly&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Expose names: use physical names (physical memory (cache coloring), disk arm position)&lt;/li&gt;
&lt;li&gt;Expose revocation: let apps choose which instances of a resource to give up&lt;/li&gt;
&lt;li&gt;Expose information: let application map in (read only) internal kernel data structures (e.g, software TLB, CPU schedule, etc)&lt;/li&gt;
&lt;li&gt;Exterminate all operating system abstractions (end-to-end)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="key-mechanisms"&gt;Key Mechanisms&lt;/h3&gt;
&lt;h4 id="secure-bindings"&gt;Secure bindings&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Bind at large granularity; access at small granularity (allow kernel to protect resources without understanding them)&lt;/li&gt;
&lt;li&gt;Do access check at bind time, not access time (e.g., when loading TLB entry for a page, not when accessing page)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hardware: TLB&lt;/li&gt;
&lt;li&gt;Software: Software TLB cache&lt;/li&gt;
&lt;li&gt;Download code (e.g., packet filter): type safe language, sandboxing, interpreters, etc&lt;/li&gt;
&lt;li&gt;Traditional file system: open file/read and write file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Challenge: secure bindings vs. Saltzer “complete mediation”&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="visible-revocation"&gt;Visible revocation&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Transparent revocation (Traditional OS)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS decides how many resources to give to apps&lt;/li&gt;
&lt;li&gt;OS chooses what to revoke and takes it&lt;/li&gt;
&lt;li&gt;Needed for performant frequent revocation (e.g., address space identifier (ASID))&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Notify on revocation (Exokernel)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;abort protocol; repossession vector; scheduler activations&lt;/li&gt;
&lt;li&gt;OS decides how many resources to give to apps&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OS chooses what to revoke, takes it, and tells application (or libOS)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Call application handler when taking away page, CPU, etc&lt;/li&gt;
&lt;li&gt;Application can react: update data structures (e.g., reduce # of threads when CPU goes away; scheduler activations) 
  and decide what page to give up&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reposes dirty disk block (store to “swap server”)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;ASIDs (processor addressing-context identifiers) are identified as a resource best revoked transparently because of 
  frequent revocation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cooperative revocation (Exokernel)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;callbacks&lt;/li&gt;
&lt;li&gt;OS decides how many resources to give to apps&lt;/li&gt;
&lt;li&gt;OS asks application or libOS to give up a resource; libOS/app decides which instance to give up&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="abort-protocol"&gt;Abort protocol&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;When voluntary revocation fails, kernel tells application what it took away. Doing so helps library to maintain valid state 
  specification&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="capabilities"&gt;Capabilities&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Encryption-based tokens to prove right to access&lt;/li&gt;
&lt;li&gt;Idea is to help kernel make access-rights decision&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple&lt;/li&gt;
&lt;li&gt;Generic across resources&lt;/li&gt;
&lt;li&gt;Hierarchical: using capabilities to protect resources enables applications to grant access rights to other applications
  without kernel intervention. Applications can also use “well-known” capabilities to share resources easily&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="others"&gt;Others&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Wakeup predicates: wake up process when arbitrary condition becomes true (checked when scheduler looking for something to run)&lt;/li&gt;
&lt;li&gt;Buffer cache registry: bind disk blocks to memory pages (applications can share cached pages)&lt;/li&gt;
&lt;li&gt;Block stat to order writes&lt;/li&gt;
&lt;li&gt;UDF&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="specific-abstractions"&gt;Specific Abstractions&lt;/h3&gt;
&lt;p&gt;Many abstractions need to be implemented in exokernel: exception handler, page protection/sharing, processor scheduling,
fork/exec, VM replacement, network protocol, file system. Here, I only list paper’s discussion related to network.&lt;/p&gt;
&lt;h4 id="network"&gt;Network&lt;/h4&gt;
&lt;h5 id="multiplexing-the-network-packet-filter"&gt;Multiplexing the network: packet filter&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Idea: load a small piece of code that examines packet and decides if it is for me&lt;/li&gt;
&lt;li&gt;Implement by downloading code into kernel: written in simple, safe language - no loops, check all mem references, etc&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Problem: what if I lie and say “yes it is for me” when it isn’t?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Solution: “assume they don’t lie”&lt;/li&gt;
&lt;li&gt;Claim: could use a trusted server to load these things or could check to make sure that a new filter never overlaps with an 
  old one [not like to solve the problem]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="application-specific-safe-handlers-ash"&gt;Application-specific safe handlers (ASH)&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Application-level message handlers that are downloaded into kernel (can reply to packet without context switch)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Example: auspex file server responds to NFS &lt;code&gt;getattr&lt;/code&gt; requests in hardware in network interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;direc message vectoring: ASH knows where message should land in user memory and thus, avoid copies&lt;/li&gt;
&lt;li&gt;dynamic integrated layer processing (e.g., do checksum as data is copied into network inteface)&lt;/li&gt;
&lt;li&gt;message initiation (fast replies)&lt;/li&gt;
&lt;li&gt;No danger of deadlock&lt;/li&gt;
&lt;li&gt;control initiation (active messages)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If we see Figure 2 of the paper: without ASH, exokernel just drops message in application buffer and later, when application 
is scheduled, application handles it. Since in the paper, round robin scheduler is used, we see linear increase in ping latency.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="os"></category></entry><entry><title>"The UNIX Time- Sharing System"</title><link href="https://zhu45.org/posts/2019/Mar/03/the-unix-time-sharing-system/" rel="alternate"></link><published>2019-03-03T11:13:00+08:00</published><updated>2019-03-03T11:13:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-03-03:/posts/2019/Mar/03/the-unix-time-sharing-system/</id><summary type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#architecture"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#file-system"&gt;File System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#process-management"&gt;Process Management&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a interative-use system with easy use (i.e., write, test, and run programs) given the hardware constraint?&lt;/p&gt;
&lt;h2 id="system-designs"&gt;System designs&lt;/h2&gt;
&lt;h3 id="architecture"&gt;Architecture&lt;/h3&gt;
&lt;p&gt;&lt;img alt="monolithic kernel" class="img-responsive" src="https://zhu45.org/images/unix.png"/&gt;&lt;/p&gt;
&lt;h3 id="file-system"&gt;File System&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Untyped data (byte oriented)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Structure of files is controlled by the programs which uses them …&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System designs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#architecture"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#file-system"&gt;File System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#process-management"&gt;Process Management&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;How to design a interative-use system with easy use (i.e., write, test, and run programs) given the hardware constraint?&lt;/p&gt;
&lt;h2 id="system-designs"&gt;System designs&lt;/h2&gt;
&lt;h3 id="architecture"&gt;Architecture&lt;/h3&gt;
&lt;p&gt;&lt;img alt="monolithic kernel" class="img-responsive" src="https://zhu45.org/images/unix.png"/&gt;&lt;/p&gt;
&lt;h3 id="file-system"&gt;File System&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Untyped data (byte oriented)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Structure of files is controlled by the programs which uses them, not by the system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hierarchical name space&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Strict hierarchy across directories&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The directory structure is constrained to have the form of a rooted tree (i.e., each directory must appear
as an entry in exactly one other, which is its parent)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Disallowing multiple links to directories&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Advantages: easier search; easier garbage collection (no cycles)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Directories are files&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A directoy behaves exactly like an ordinary file execpt that it cannot be written on by unprivileged programs, 
  so that the system controls the contents of directories; anyone with proper permission can read a directory just like
  ordinary files.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Linking: same nondirectory file may appear in several directories under possibly different names&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Treating I/O devices as files&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Special files exist for each communication line, each disk, each tape drive, and for physical core memory&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;File and device I/O are as similar as possible&lt;/li&gt;
&lt;li&gt;File and device names have the same syntax and meaning &lt;/li&gt;
&lt;li&gt;Special files are subject to the same protection mechanism as regular files &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mount&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Removable storage; expand storage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mount replaces a leaf of the hierarchy tree (the ordinary file) by a whole new subtree (the hierarchy stored
  on the removable volume)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;No cross-volume links allowed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set-User-ID (right amplification)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setuid (set user ID on execution) permits users to run certain programs with escalated privileges (i.e., execute
  a program as someone else)&lt;/li&gt;
&lt;li&gt;Example: when a user wants to change their password, they run the passwd command. The passwd program is owned by the 
  root account and marked as setuid, so the user is temporarily granted root access for that very limited purpose.
  Since user id of invoker is known, it’s passwd program responsibility to make sure the invoker’s proper behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;File descriptor&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A small integer used to identify the file in subsequent calls to read, write&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Used as a index to a system table that contains file’s device, i-number, and read/write pointer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Filter programs (e.g., &lt;code&gt;ls | pr -2 | opr&lt;/code&gt;) do not know the name of input or output files&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;“Handle with access rights” (that is a capability, which is an abstraction that makes protected sharing easier); it is a capability because the right can be transferred to other processes that want to access the file&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implementation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A directory contains file name and a pointer to file; the pointer is the i-number of the file. When the file 
  is accessed, its i-number is used as an index into a system table (i-list) stored in a known part of the device
  on which the directory resides.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;i-number is used as a index to find corresponding entry inode in i-list; inode contains description of file&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A small (nonspecial) file fits into eight or fewer blocks; in this case the addresses of the blocks themselves are stored.       For large (nonspecial) files, each of the eight device addresses may point to an indirect block of 256 addresses of blocks       constituting the file itself. These files may be as large as &lt;span class="math"&gt;\(8 \cdot 256 \cdot 512\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;… more on paper&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="process-management"&gt;Process Management&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;An image is a computer execution environment. It includes a core image (contains three segments: code, heap, stack), general
register values, status of open files, current directory, and the like. An image is the current state of a pseudo computer.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;I would like to think about image as a snapshot of the process, which cannot be modified. This is useful during multitasking as OS can save current process states as an image before running other processes. At some point, OS can load image back again to continue running the process. See &lt;a href="https://stackoverflow.com/questions/41865240/whats-the-difference-between-a-process-and-a-process-image"&gt;here&lt;/a&gt; and &lt;a href="http://www.tldp.org/LDP/LG/issue23/flower/psimage.html"&gt;here&lt;/a&gt; for more info.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A process is the execution program of an image.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Building blocks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Fork, exec, wait&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;File I/O structure&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Fork’d child shares parent’s open files; have indenpendent copy of the original core image&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pipes: not a completely general mechanism since the pipe must be set up by a common ancestor of the processes involved
(working mechanism see paper)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Standard I/O&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Programs executed by the shell start off with two open files which have file descriptors 0 (stdin) and 1 (stdout)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enables redirection and pipelines easily&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Shell&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;bg execution&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;initialization: last step in the initialization of UNIX is creation of a single process and the invocation of 
  &lt;em&gt;init&lt;/em&gt;; init creates child processes which will later become shells.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On treating I/O devices as files advantages: (1) seems useful but high-performance implementation tend to treat
  e.g., network I/O differently from disk. (2) seems useless (“ioctl” interface for device-specific functionality is terrible); 
  (3) is compelling&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;“There have been three versions of UNIX.” Fred Brooks is right&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I learn some new usage in UNIX (e.g., &lt;code&gt;pr&lt;/code&gt; - paginates its input with dated headings; &lt;code&gt;ed&lt;/code&gt; as a editor; &lt;code&gt;(date; ls) &amp;gt; x&lt;/code&gt; - 
use parentheses)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2019"></category><category term="os"></category><category term="papers"></category></entry><entry><title>Brush up OS</title><link href="https://zhu45.org/posts/2019/Jan/23/brush-up-os/" rel="alternate"></link><published>2019-01-23T22:24:00+08:00</published><updated>2019-01-23T22:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2019-01-23:/posts/2019/Jan/23/brush-up-os/</id><summary type="html">&lt;p&gt;This post aims to prepare myself for the upcoming &lt;a href="http://www.cs.utexas.edu/~rossbach/380L/index.html"&gt;CS380L Advanced Operating Systems&lt;/a&gt; offered by
&lt;a href="http://www.cs.utexas.edu/~rossbach/"&gt;Christopher J. Rossbach&lt;/a&gt;. The questions are actually from his &lt;a href="http://www.cs.utexas.edu/~rossbach/380L/hw/hw1.pdf"&gt;HW1&lt;/a&gt; aka. “Swapping in the state from undergraduate OS”.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#brush-up"&gt;Brush up&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#definitions"&gt;Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#short-answer"&gt;Short answer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#virtual-memory-addressing"&gt;Virtual memory addressing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#page-replacement"&gt;Page replacement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#multiprocessing"&gt;Multiprocessing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#achieving-fast-file-reads"&gt;Achieving fast file reads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#synchronization"&gt;Synchronization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#networking"&gt;Networking …&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;This post aims to prepare myself for the upcoming &lt;a href="http://www.cs.utexas.edu/~rossbach/380L/index.html"&gt;CS380L Advanced Operating Systems&lt;/a&gt; offered by
&lt;a href="http://www.cs.utexas.edu/~rossbach/"&gt;Christopher J. Rossbach&lt;/a&gt;. The questions are actually from his &lt;a href="http://www.cs.utexas.edu/~rossbach/380L/hw/hw1.pdf"&gt;HW1&lt;/a&gt; aka. “Swapping in the state from undergraduate OS”.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#brush-up"&gt;Brush up&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#definitions"&gt;Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#short-answer"&gt;Short answer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#virtual-memory-addressing"&gt;Virtual memory addressing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#page-replacement"&gt;Page replacement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#multiprocessing"&gt;Multiprocessing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#achieving-fast-file-reads"&gt;Achieving fast file reads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#synchronization"&gt;Synchronization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#networking"&gt;Networking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#serving-multiple-clients"&gt;Serving multiple clients&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="brush-up"&gt;Brush up&lt;/h2&gt;
&lt;h3 id="definitions"&gt;Definitions&lt;/h3&gt;
&lt;p&gt;Define the following terms:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Internal and external fragmentation.  Which of them can occur in a paging system? A system with pure segmentation?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fragmentation happens when we talk about memory allocation (e.g., user requests memory through &lt;code&gt;malloc()&lt;/code&gt;; OS manages physical
memory when using segmentation to implement virtual memory). There are two types of fragmentation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;internal fragmentation&lt;/strong&gt;: unused memory within a unit of allocation: if an allocator hands out chunks of memory bigger than that requested,
any unasked for (and thus unused) space in such a chunk is considered &lt;em&gt;internal&lt;/em&gt; fragmentation (because the waste occurs inside the allocated unit).
Metaphorically speaking, internal fragmentation happens when a party of three at a table for four.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;external fragmentation&lt;/strong&gt;: unused memory between units of allocation: the free space gets chopped into little pieces of different sizes and is thus
fragmented; subsequent requests may fail because there is no single contiguous space that can satisfy the request, even though the total amount of free
space exceeds the size of the request. Metaphorically speaking, external fragmentation happens when two fixed tables for two but a party of four.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a paging system, since the free space is divided into fixed-size units (i.e., pages), no external fragmentation can happen: a page request will
always get satisified as all page size are equal; we can simply return one of them. However, internal fragmentation can still happen. For example,
if the page size is 4KB and we request 3KB memory, then there will be 1KB unused memory within the returned page.&lt;/p&gt;
&lt;p&gt;In a system with pure segmentation, only extenral fragmentations can happen. Since segments are variable-sized units, external fragmentation cannot be avoided. However, the system can give out exact size of requested memory (no paging exists), then there is no internal fragmentation.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-segmentation.pdf"&gt;Chapter 16&lt;/a&gt; and &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-freespace.pdf"&gt;Chapter 17&lt;/a&gt; offer more on segmentation, which causes fragmentation, and free-space management that handles external fragmentation issue.&lt;/p&gt;
&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Translation look-aside buffer (TLB).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;TLB is part of the chip’s memory-management unit (MMU). It serves as a hardware cache of popular virtual-to-physical address translations
(i.e., virtual page number to physical frame number translations)&lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interrupt.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Interrupts are essentially requests for attention. In the same way, peripherals in a computer system can request the attention of the processor. The event that makes a microprocessor stop executing one routine to perform some other routine to service a request, is called an INTERRUPT&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;2&lt;/a&gt;&lt;/sup&gt;. In other words, an  interrupt  is  an  electrical signal  that  causes  the  processor  to  stop  the  current  execution and  begin  to  execute  interrupt  handler  code.  Interrupts
are asynchronous excpetions. Asynchronous here means “not related to instruction that just executed”&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Distributed shared memory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Distributed shared memory is a memory architecture that a cluster of nodes share the same logical address space but physical
memories are from each node in the cluster and connected via the network (i.e., a form of memory architecture where physically separated memories can be addressed as one logically shared address space) &lt;sup id="fnref:15"&gt;&lt;a class="footnote-ref" href="#fn:15"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Stateful  and  stateless  servers.   Also,  list  two  file  systems,  one  that is stateful and one that is stateless, and explain how having or not having state affects file service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Stateless server means the server does not keep track of anything about what is happening at each client (e.g., server does not
maintain which client open what file on its side). Stateful server is the opposite of the stateless server. For example, 
server keeps track of what client accesses what files so that when the server’s file copy is modified (e.g., by some other clients
who also access the same file), server can inform clients to invalidate their cache of the same file.&lt;/p&gt;
&lt;p&gt;A classic stateless file system is &lt;a href="https://zhu45.org/posts/2018/May/01/suns-network-file-system-nfs/"&gt;NFS with NFSv2 protocol&lt;/a&gt; (&lt;a href="http://www.sane.nl/events/sane2000/papers/pawlowski.pdf"&gt;NFSv4 protocol&lt;/a&gt; makes NFS become a stateful server as well). &lt;a href="https://zhu45.org/posts/2018/May/02/the-andrew-file-system-afs/"&gt;AFS&lt;/a&gt; is a stateful file system. &lt;/p&gt;
&lt;p&gt;Not having state makes crash recovery on the server side fast: server doesn’t need to recover any client-side information 
(thanks to stateless) and on server failure, clients can simply retry the request. However, with stateless, clients need
to constantly contact server to validate their cache, which impose extra load to server. Furthermore, clients need to pass 
extra information (e.g., file handle) when perform system calls, which impose extra overhead to clients. Having state complicates
the crash recovery: server needs to initiate cache validation to the clients; clients also need to send out heartbeat message to
server. However, with state, client doesn’t need to constantly contact to validate its cache (wait for server’s callback).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Swapping.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since all pages cannot reside in the physical memory, to support large address space, we use part of disk (e.g., swap space) by
swapping pages in and out between physical memory and swap space &lt;sup id="fnref:11"&gt;&lt;a class="footnote-ref" href="#fn:11"&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Inverted page table.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Inverted page table (along with multi-level page tables) aims to save memory space taken by the page tables. Instead of having one page table per process, we keep a single page table that has an entry for each &lt;em&gt;physical page&lt;/em&gt; of the system. The entry tells us which process is using this page, and 
which virtual page of that process maps to this physical page &lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;6&lt;/a&gt;&lt;/sup&gt;. PowerPC uses this technique. &lt;/p&gt;
&lt;!-- inverted: hash table; each entry contains &lt;pid, corresponding virutal page number&gt;
64-bit linux uses inverted page table (TODO)--&gt;
&lt;blockquote&gt;
&lt;p&gt;Disk sector, track, and cylinder.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A disk &lt;strong&gt;sector&lt;/strong&gt; refers to 512-byte block on the disk (aside note, drive manufacturers guarantee that a single 512-byte write is 
atomic). Sectors of disk are organized as a set of concentric circles; each concentric circle of sectors is called a &lt;strong&gt;track&lt;/strong&gt;
&lt;sup id="fnref:13"&gt;&lt;a class="footnote-ref" href="#fn:13"&gt;7&lt;/a&gt;&lt;/sup&gt;. A &lt;strong&gt;cylinder&lt;/strong&gt; is a set of tracks on different surfaces of a hard dirve that are the same distance from the center
of the drive; it is called a cylinder because of its clear resemblance to the so-called geometrical shape &lt;sup id="fnref:14"&gt;&lt;a class="footnote-ref" href="#fn:14"&gt;8&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thrashing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- Ideally, pages in the set of running processes should not be removed from the physical memory as they will have to be brought back in again. However, swaping can happens. However, if swaping happens too often and thus, most of CPU time is devoted to this activity, we run into *thrashing* situation. --&gt;
&lt;p&gt;The situation when memory demands of the set of running processes exceeds the available physical memory. System performace degrades due to the fact that system CPU time is dominated by the activity of swaping pages in and out between physical memory and swap space on disk &lt;sup id="fnref:10"&gt;&lt;a class="footnote-ref" href="#fn:10"&gt;9&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id="short-answer"&gt;Short answer&lt;/h3&gt;
&lt;p&gt;Provide a short answer to each of the following questions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Give a reason why virtual memory address translation is useful even if  the  total  size  of  virtual  memory  (summed  over  all  programs) is guaranteed to be smaller than physical memory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Virtual memory address translation is useful in providing isolation (safety) across different processes: OS can make sure that one proacess cannot access part of physical memory that is owned by the other process. In addition, address translation helps OS to better manage the underlying physical memory: every process thinks address space starts at 0, which may not be true on the physical memory; for better memory management, OS may relocate the address space to some other physical address. Address translation enables OS to perform such memory management while makes the relocation be transparent to process &lt;sup id="fnref:16"&gt;&lt;a class="footnote-ref" href="#fn:16"&gt;10&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;!-- same physical page can be shared across multiple processes; --&gt;
&lt;blockquote&gt;
&lt;p&gt;Compare and contrast access control lists and capabilities.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In an access control list model of security, the authorities are bounded to the objects being secured (e.g., file A can be r/w by user Alice). By contrast,
in the capabilities model, the authorities are bound to objects seeking access &lt;sup id="fnref:17"&gt;&lt;a class="footnote-ref" href="#fn:17"&gt;11&lt;/a&gt;&lt;/sup&gt; (e.g., UNIX file descriptors are capabilities: authorities are 
bounded to file descriptors, which reflect rights on objects like files or sockets &lt;sup id="fnref:20"&gt;&lt;a class="footnote-ref" href="#fn:20"&gt;12&lt;/a&gt;&lt;/sup&gt;).&lt;/p&gt;
&lt;p&gt;As one can see, with the ACL model, each object has just one list, while with the capability model, each object has a whole set of different, separable capabilities. For example, in capability model, a process has different capabilities depending on the objects it tries to access.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://homepage.divms.uiowa.edu/~jones/security/notes/18.shtml"&gt;This page&lt;/a&gt; has a nice example: file “aaa” has ACL as “Alice:R/W, Bob:R, Carol:R”. File “aaa” is the object being secured. “Alice” has capabilities “aaa:R/W, bbb:R, ccc:R”. “Alice” as a user is the object seeking access.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The  length  of  the  time  slice  is  a  parameter  to  round  robin  CPU scheduling.  What is the main problem that occurs if this length is too long?  Too short?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are two important metrics in scheduling: &lt;em&gt;turnaround time&lt;/em&gt; and &lt;em&gt;response time&lt;/em&gt;. &lt;em&gt;turnaround time&lt;/em&gt; of a job is
defined as &lt;span class="math"&gt;\(T_{completion} - T_{arrival}\)&lt;/span&gt; (the time at which the job completes minus the time at which the job arrived in the
system). &lt;em&gt;response time&lt;/em&gt; is defined as &lt;span class="math"&gt;\(T_{firstrun} - T_{arrival}\)&lt;/span&gt; (the time from when the job arrives in a system to the first time it is scheduled). Round robin (RR) CPU scheduling is optimized towards
response time. If time slice is too long, then the response time is worse. By contrast, if time
slice is too short, the cost of context switching will dominate overall performance, which means less work is done during the time slice &lt;sup id="fnref:18"&gt;&lt;a class="footnote-ref" href="#fn:18"&gt;13&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;List an advantage and a disadvantage to increasing the virtual memory page size.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The advantages of increasing the virtual memory page size are: reduces page table size &lt;sup id="fnref:6"&gt;&lt;a class="footnote-ref" href="#fn:6"&gt;14&lt;/a&gt;&lt;/sup&gt;, improves TLB hit rate &lt;sup id="fnref:7"&gt;&lt;a class="footnote-ref" href="#fn:7"&gt;15&lt;/a&gt;&lt;/sup&gt;. The disadvantage is the 
internal fragmentation (i.e., waste &lt;em&gt;within&lt;/em&gt; each page; the waster is &lt;em&gt;internal&lt;/em&gt; to the unit of allocation) &lt;sup id="fnref2:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;!-- data block size determines largest file size (related to inode) --&gt;
&lt;h3 id="virtual-memory-addressing"&gt;Virtual memory addressing&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose we have a machine that uses a three-level page table system.
A 32-bit virtual address is divided into four fields of widths a, b, c, and d bits from left to right.
The first three are indices into the three levels of page table; the fourth, d, is the offset.  Express the
number of virtual pages available as a function of a, b, c, and d. Give one advantage and one disadvantage to multi-level page tables.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since we have a three-level page table system, then &lt;span class="math"&gt;\(a\)&lt;/span&gt; corresponds to Page Directory Index (PDI) 0, &lt;span class="math"&gt;\(b\)&lt;/span&gt; corresponds to PDI 1,
&lt;span class="math"&gt;\(c\)&lt;/span&gt; corresponds to Page Table Index. Each page contains &lt;span class="math"&gt;\(2^c\)&lt;/span&gt; Page Table Entries (PTE). Page Directory 1 needs one entry per page
and contains &lt;span class="math"&gt;\(2^b\)&lt;/span&gt; entries. Similarly, Page Directory 0 needs one entry per page, which contains one Page Directory 1 and there are
&lt;span class="math"&gt;\(2^a\)&lt;/span&gt; entries. Thus, there are &lt;span class="math"&gt;\(2^a\)&lt;/span&gt; Page Directory 1, and each Page Directory 1 can point to &lt;span class="math"&gt;\(2^b\)&lt;/span&gt; pages, and each page contains
&lt;span class="math"&gt;\(2^c\)&lt;/span&gt; PTEs, and each PTE corresponds to one virtual page. Therefore, there are &lt;span class="math"&gt;\(2^{a+b+c}\)&lt;/span&gt; virutal pages. Another way of cacluation is
that the physical frame size is &lt;span class="math"&gt;\(2^d\)&lt;/span&gt;, which is equal to page size. Since the address space is 32 bit, there are &lt;span class="math"&gt;\(\frac{2^{32}}{2^d}\)&lt;/span&gt; virtual pages
&lt;sup id="fnref:8"&gt;&lt;a class="footnote-ref" href="#fn:8"&gt;16&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The advantages of multi-level page tables are that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The multi-level table only allocates page-table space in proportion to the amount of address space we are using (more compact to support sparse page table)&lt;/li&gt;
&lt;li&gt;each portion of page table fits into a page makes memory management easier: we don’t have to find contiguous physical memory chunk that can contain the linear page table; we can place page-table pages whereever we want in the physical memory. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The disadvantage is that additional memory accesses to look up a valid translation 
(e.g., for 3-level page table system, we have three additional memory accesses: access Page Directory Entry 0 (PDE0), access PDE1, access PTE)&lt;sup id="fnref:9"&gt;&lt;a class="footnote-ref" href="#fn:9"&gt;17&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id="page-replacement"&gt;Page replacement&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose a machine with 4 physical pages starts running a program (in other words, the physical pages are initially empty).  The
program references the sequence of virtual pages as follows: A B C D E D C B A E D C B A C E
For each of the following paging algorithms, replicate the reference pattern
and underline each reference that causes a page fault (or make references
that cause a page fault uppercase, and those that don’t lowercase):&lt;/p&gt;
&lt;p&gt;LRU.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;LRU stands for Least-Recently-Used, which is one of the page replacement policies (in practice, we use clock algorithm to 
approximate LRU &lt;sup id="fnref:12"&gt;&lt;a class="footnote-ref" href="#fn:12"&gt;18&lt;/a&gt;&lt;/sup&gt; to avoid heavy overhead). The trace of the memory references with LRU policy shown below:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Access&lt;/th&gt;
&lt;th&gt;Hit/Miss&lt;/th&gt;
&lt;th&gt;Evict&lt;/th&gt;
&lt;th&gt;Resulting Cache State (LRU at front, MRU at tail)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B,C,D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,E,D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,E,D,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;E,D,C,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;D,C,B,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;C,B,A,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;B,A,E,D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;A,E,D,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;E,D,C,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;D,C,B,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;D,B,A,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;B,A,C,E&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;From the table, we have A,B,C,D,E,d,c,b,A,E,D,C,B,A,c,E.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;FIFO.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;FIFO means first-in, first-out: pages are placed in a queue as the order they are brought into physical memory; when
replacement occurs, the first-in page is evicted. The similar trace of memory references with FIFO policy shown below:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Access&lt;/th&gt;
&lt;th&gt;Hit/Miss&lt;/th&gt;
&lt;th&gt;Evict&lt;/th&gt;
&lt;th&gt;Resulting Cache State&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B,C,D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;D,E,A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;D,E,A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;E,A,B,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;E,A,B,C&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Thus, we have A,B,C,D,E,d,c,b,A,e,d,c,B,a,C,e.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Optimum.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Optimal policy means we want to replace the page that will be accessed &lt;em&gt;furthest in the future&lt;/em&gt; and doing so will result in
the optimal policy with fewest possible cache misses. The resulting trace with optimal policy follows:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Access&lt;/th&gt;
&lt;th&gt;Hit/Miss&lt;/th&gt;
&lt;th&gt;Evict&lt;/th&gt;
&lt;th&gt;Resulting Cache State&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B,C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;A,B,C,D&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;B,C,D,E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,D,E,A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;Miss&lt;/td&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;C,E,A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,E,A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,E,A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E&lt;/td&gt;
&lt;td&gt;Hit&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;C,E,A,B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We have A,B,C,D,E,d,c,b,A,e,d,c,B,a,c,e.&lt;/p&gt;
&lt;h3 id="multiprocessing"&gt;Multiprocessing&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose you have a large source program containing m files that you want to compile.  You have a cluster of
n “shared-nothing” workstations, where n &amp;gt; m, on which you may compile your files.  At best you will get an m-fold speedup compared to a single processor.  List at least three reasons as to why the actual speedup might be less than this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Interconnection overhead. To perform distributed compilation, there are network communication cost and coordination cost about assigning files to different workstations, and communication across machines during the compilation (e.g., A file on one workstation may have dependencies of the files assigned to other machines. To make the file into object code file, file copies from other machines are needed).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Computation graph may have dependency that is not parallelizable (e.g., linking).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Resources limitation. We have a cluster of n workstations but we may not have fully-usage of the underlying resources (i.e., our jobs may be subject to cluster coordinator scheduling).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;File size are unequal. Suppose we have 5 files to compile: first 4 need 1s compilation time while the last one needs 10 minutes. Then, whether we perform distributed compilation or not doesn’t make difference: the last file will make become bottleneck and we cannot get 5-fold speedup.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="achieving-fast-file-reads"&gt;Achieving fast file reads&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;(a) Give at least three strategies that a file system can employ to reduce the time a program spends waiting for data reads to complete.  (b) For each strategy you listed,  describe a read pattern for which the strategy  would  do  well,  and  one  for  which  the  strategy  would  do poorly&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Use cache (e.g., buffer cache, page cache of the virtual memory) to pre-read the requested data block and several subsequent
   data blocks at the same time on &lt;code&gt;open()&lt;/code&gt;. Then, data can be read from cache in memory instead of disk to avoid expensive
   disk I/O.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequential read performs well&lt;/li&gt;
&lt;li&gt;Random read performs poorly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can compress the data when we store them at the first place. By reducing the size of file, we can reduce the amount of disk I/O done for reading the file and spend more CPU time to uncompress the data, which is naturally faster than doing disk I/O instead.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Big read performs well&lt;/li&gt;
&lt;li&gt;Small read performs poorly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can use RAID Level 0 (i.e., striping) to spread the data block across the disks in a round-robin fashion. When we read the data, we can utilize 
multiple disks in parallel. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequential read performs well&lt;/li&gt;
&lt;li&gt;Random read performs poorly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can place file’s inode close to file’s data blocks so that during data read, we can reduce seek and rotational delay costs of HDD.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequential read performs well&lt;/li&gt;
&lt;li&gt;Random read performs poorly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Prefetching: we can try to predict what data/files the user will read next and buffer the file content into memory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sequential read performs well&lt;/li&gt;
&lt;li&gt;Random read performs poorly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Build index to the most visited files (i.e., direct pointer to the files) so that we don’t have to traverse internal data structure of file system (i.e., similar to TLB).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read hot data performs well &lt;/li&gt;
&lt;li&gt;Read cold data performs poorly&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="synchronization"&gt;Synchronization&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Your OS has a set of queues, each of which is protected by a lock.  To enqueue or dequeue an item, a thread must hold the lock
associated with the queue. You need to implement an atomic transfer routine that dequeues an item
from one queue and enqueues it on another.  The transfer must appear to occur atomically.
This is your first attempt:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* the thing being transferred */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;You may assume that &lt;code&gt;queue1&lt;/code&gt; and &lt;code&gt;queue2&lt;/code&gt; never refer to the same queue. Also, assume that you have a function &lt;code&gt;Queue::Address()&lt;/code&gt;
which takes a queue and returns, as an unsigned integer, its address.&lt;/p&gt;
&lt;p&gt;(a) Explain how  using this implementation of &lt;code&gt;transfer()&lt;/code&gt; can lead to deadlock&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One possible scenario of deadlock using &lt;code&gt;transfer()&lt;/code&gt; is illustrated below. Note that &lt;code&gt;queue1&lt;/code&gt; and &lt;code&gt;queue2&lt;/code&gt; in &lt;code&gt;transfer()&lt;/code&gt;
are replaced with queues that they are pointing to (time increases with the row’s number):&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Thread1 (&lt;code&gt;transfer(q1,q2)&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Thread2 (&lt;code&gt;transfer(q2,q1)&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;q1-&amp;gt;lock.Acquire();&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;thing = q1-&amp;gt;Dequeue();&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;if (thing != NULL)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;interrupt: switch to Thread2&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;q2-&amp;gt;lock.Acquire();&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;thing = q2-&amp;gt;Dequeue();&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;if (thing != NULL)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;q1-&amp;gt;lock.Acquire(); // block &amp;amp; wait on q1's lock&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;interrupt: switch to Thread1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;q2-&amp;gt;lock.Acquire(); // block &amp;amp; wait on q2's lock&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;(b) Write a modified  version  of &lt;code&gt;transfer()&lt;/code&gt; that avoids deadlock and does the transfer atomically.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;pthread_mutex_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PTHREAD_MUTEX_INITIALIZER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* the thing being transferred */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;pthread_mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;pthread_mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alternatively, we can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* the thing being transferred */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;pthread_mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;pthread_mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;(c) If  the  transfer  does  not  need  to  be  atomic,  how  might  you  change your solution to achieve a higher degree of concurrency?  Justify why your modification increases concurrency.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* the thing being transferred */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;/* lock1 for Dequeue() */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* lock2 for Enqueue() */&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’s more fine-grained than the previous approach because compared to previous approach which only one thread can touch one queue, two threads can touch
on the same queue: one for enqueue and one for dequeue.&lt;/p&gt;
&lt;p&gt;Alternatively, we can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Queue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* the thing being transferred */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Dequeue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;queue1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Acquire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;queue2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The length of time we hold lock is shorter (i.e., at any time, the function is holding only one lock).&lt;/p&gt;
&lt;h3 id="networking"&gt;Networking&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;You  are  developing  a  network  protocol  for  the  reliable  delivery of fixed-sized messages over unreliable networks.  You are using a
sequence number in each message to allow the receiver to eliminate duplicates, but you still have three design alternatives to consider.
The design alternatives are:  (1) the sender must receive an acknowledgement for the previously sent message before it can send the next message
in  the  sequence,  (2)  the  sender  can  transmit  up  to n unacknowledged messages, but the receiver will discard any messages that are received out
of  sequence  (in  other  words,  it  will  only  acknowledge  a  message  if  it  is received in sequence), and (3) the sender can transmit up to
n unacknowledged messages, and the receiver will acknowledge each on receipt, even if they arrive out of order.
For each alternative, answer the following questions&lt;/p&gt;
&lt;p&gt;(a) Explain what state the receiver must keep around to implement each of  the  three  alternatives  (remember,  the  receiver  must  be  able  to detect and discard duplicates).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;For 1), we keep track of expected sequence # (or last received sequence #)&lt;/li&gt;
&lt;li&gt;For 2), we keep track of expected sequence # (or last received sequence #)&lt;/li&gt;
&lt;li&gt;For 3), we keep track of a buffer with size &lt;span class="math"&gt;\(n\)&lt;/span&gt; and make sure there is no duplicates by sorting them. If there is a duplicate, the ack will be sent 
with the missing sequence # back to sender. The receiver only increments the lower bound sequence # of buffer when &lt;span class="math"&gt;\(n\)&lt;/span&gt; messages within the buffer satisfying the requirement (invariant: all the sequence number smaller than lower bound is well-ordered and no missing).&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;(b) Suppose two machines are communicating across a bi-directional network  link  with  fixed-size  messages.   Acknowledgement  packets  are 
also fixed-size.  One machine, the sender, is transmitting a very large file to the other machine, the receiver.  That is, the sender is transmitting 
a large number of messages that make up this file.  Discuss briefly  how  each  alternative’s  data  bandwidth  is  expected  to  vary
given different underlying network characteristics.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If there is no loss of the packets during the transit, (3) has the highest data bandwidth as there are maximum amount of packets in the flight and receiver
will acknowledge even the packets are out of order. By contrast, (1) has the lowest data bandwidth due to sender can only send out a packet when an ack is 
received. If loss is seldom, (3) has highest data bandwidth. If there is loss, the more servere the loss, the more bandwidth (1) can achieve compared to others. (3) is worst in this case because (3) performs lots of useless work (send out n packets but get dropped anyway; leads to congestion).&lt;/p&gt;
&lt;p&gt;When latency is small, (3) is the most effective; (1) is the worst. When latency is large, (1) is the most effective; (2) is the worst because of possible 
congestions and the order of packets is very likely be out-of-order, and then discarded by receiver, and sender will need to resend again.&lt;/p&gt;
&lt;p&gt;When everything is good, (2) and (3) are similar.&lt;/p&gt;
&lt;!-- Latency impacts the order of packets. --&gt;
&lt;!-- latency: the time taken by a packet from sender to receiver --&gt;
&lt;h3 id="serving-multiple-clients"&gt;Serving multiple clients&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;There are two main approaches to organizing a server daemon, such as a web server: a) Create  a  new  kernel  thread  for  each  client  (for  each  web browser connection); b) Use a single process responding to all clients, usually based on the &lt;code&gt;select()&lt;/code&gt; system call. Compare and contrast these two approaches.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Multi-threaded architecture &lt;sup id="fnref:19"&gt;&lt;a class="footnote-ref" href="#fn:19"&gt;19&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A pool of worker threads handle incoming requests&lt;/li&gt;
&lt;li&gt;One worker thread usually corresponds to one connection&lt;/li&gt;
&lt;li&gt;A dispatcher thread blocks socket on connection and once establised, the connection is passed to a queue of connections where worker threads 
can take connections from the queue and handle the request&lt;/li&gt;
&lt;li&gt;Queue of connections is bounded: awaiting connections to be handled is limited; extra connections will be rejected&lt;/li&gt;
&lt;li&gt;Predicatable latency and prevents total overload&lt;/li&gt;
&lt;li&gt;Can utilize multiple CPU cores (*)&lt;/li&gt;
&lt;li&gt;A synchronous, blocking I/O architecture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Event-based architecture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;asyncronous, non-blocking&lt;/li&gt;
&lt;li&gt;one process (thread) handles multiple connections&lt;/li&gt;
&lt;li&gt;Events are queued and will be dequeued by the event loop (single thread)&lt;/li&gt;
&lt;li&gt;Each event has corresponding event handler&lt;/li&gt;
&lt;li&gt;Usually the event is handled in a cascade of callbacks&lt;/li&gt;
&lt;li&gt;Depends on the implementation, the event can be handled in the same thread as the event loop (i.e., event loop will be blocked when handle the event)
or a pool of threads will be used for event handler&lt;/li&gt;
&lt;li&gt;Compared to multi-threaded architecture, number of threads used is reduced (consequently, get rid of excessive context switching overhead, no thread
stack for each connection); event-based architecture scales with increasing throughput; latency of requests increases linearly when overload&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key difference between these two architectures is who do the scheduling: in multi-threaded architecutre, OS performs scheduling by performing context-switch of different worker threads. However, for event-based architecture, event loop thread essentially works as a scheduler: multiplexing multiple connections
to a single flow of execution. In addition, for event-based architecture, we need to implement preemptive interrupt on event handler thread pool as well.&lt;/p&gt;
&lt;p&gt;In addition, the kernel threads approach can have easily lead to system crash due to all the work is in kernel-space. In addition, kernel thread has higher context-switch overhead compared to threads within single process of the second approach &lt;sup id="fnref2:20"&gt;&lt;a class="footnote-ref" href="#fn:20"&gt;12&lt;/a&gt;&lt;/sup&gt;. However, kernel threads can scale up with number of CPU cores while single process approach cannot benefit from multi-core.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;taken from OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-tlbs.pdf"&gt;Chapter 19&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;taken from &lt;a href="http://web.archive.org/web/20040322145339/http://members.iweb.net.au:80/~pstorr/pcbook/book2/irq.htm"&gt;Phil Storrs PC Hardware book&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="https://www.cs.utexas.edu/users/ans/classes/cs439/schedule.html"&gt;Alison’s CS439 Lec 02&lt;/a&gt; and CSAPP (2nd edition) 8.1.2 &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:15"&gt;
&lt;p&gt;See [@@Protic:1996] and &lt;a href="https://en.wikipedia.org/wiki/Distributed_shared_memory"&gt;Wikipedia&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:15" title="Jump back to footnote 4 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:11"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-beyondphys.pdf"&gt;Chapter 21&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:11" title="Jump back to footnote 5 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;taken from OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf"&gt;Chapter 20&lt;/a&gt;. More details found in Alison’s CS439 Lec 12 “Virtual Memory: Mechanisms” &lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 6 in the text"&gt;↩&lt;/a&gt;&lt;a class="footnote-backref" href="#fnref2:4" title="Jump back to footnote 6 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:13"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-disks.pdf"&gt;Chapter 37&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:13" title="Jump back to footnote 7 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:14"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-ffs.pdf"&gt;Figure in Chapter 41.3&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:14" title="Jump back to footnote 8 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:10"&gt;
&lt;p&gt;The term is originally defined in [@@Denning:1968:TCP:1476589.1476705]. But I find &lt;a href="https://www.computer.org/csdl/mags/co/1976/10/01647183.pdf"&gt;this article’s explanation&lt;/a&gt; is more intuitive. &lt;a class="footnote-backref" href="#fnref:10" title="Jump back to footnote 9 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:16"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-mechanism.pdf"&gt;Chapter 15&lt;/a&gt; for more details. &lt;a class="footnote-backref" href="#fnref:16" title="Jump back to footnote 10 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:17"&gt;
&lt;p&gt;See &lt;a href="http://www.skyhunter.com/marcs/capabilityIntro/capacl.html"&gt;Capabilities and ACLs&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:17" title="Jump back to footnote 11 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:20"&gt;
&lt;p&gt;See [@@shapiro1999eros] and [@@watson2010capsicum] &lt;a class="footnote-backref" href="#fnref:20" title="Jump back to footnote 12 in the text"&gt;↩&lt;/a&gt;&lt;a class="footnote-backref" href="#fnref2:20" title="Jump back to footnote 12 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:18"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/cpu-sched.pdf"&gt;Chapter 7&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:18" title="Jump back to footnote 13 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;One cacluation example can be found from OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf"&gt;Chapter 20.1&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:6" title="Jump back to footnote 14 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-tlbs.pdf"&gt;Chapter 19.2 example&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:7" title="Jump back to footnote 15 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf"&gt;Chapter 20&lt;/a&gt;, &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-paging.pdf"&gt;Chapter 18&lt;/a&gt;, and &lt;a href="https://www.cs.utexas.edu/~lorenzo/corsi/cs372/06F/hw/3sol.html"&gt;this page&lt;/a&gt; may help with cacluation. &lt;a class="footnote-backref" href="#fnref:8" title="Jump back to footnote 16 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-smalltables.pdf"&gt;Chapter Figure 20.6&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:9" title="Jump back to footnote 17 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:12"&gt;
&lt;p&gt;See OSTEP &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/vm-beyondphys-policy.pdf"&gt;Chapter 22&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:12" title="Jump back to footnote 18 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:19"&gt;
&lt;p&gt;See &lt;a href="http://berb.github.io/diploma-thesis/original/042_serverarch.html"&gt;Concurrent Programming for Scalable Web Architectures&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:19" title="Jump back to footnote 19 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:21"&gt;
&lt;p&gt;See &lt;a href="https://courses.cs.washington.edu/courses/cse451/11sp/section/kim_section4.pdf"&gt;CSE451&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:21" title="Jump back to footnote 20 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2019"></category><category term="os"></category><category term="system concepts"></category></entry><entry><title>Modify char in another function</title><link href="https://zhu45.org/posts/2018/Sep/26/modify-char-in-another-function/" rel="alternate"></link><published>2018-09-26T10:00:00+08:00</published><updated>2018-09-26T10:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-09-26:/posts/2018/Sep/26/modify-char-in-another-function/</id><summary type="html">&lt;p&gt;Almost two years ago, I write a &lt;a href="https://zhu45.org/posts/2017/Jan/08/modify-array-inside-function-in-c/"&gt;post&lt;/a&gt; on how to 
modify an array in one function through another function in C. I did pretty detailed study through GDB there but 
I find that the illustration is lengthy to read. In this post, I try to show the same
concept …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Almost two years ago, I write a &lt;a href="https://zhu45.org/posts/2017/Jan/08/modify-array-inside-function-in-c/"&gt;post&lt;/a&gt; on how to 
modify an array in one function through another function in C. I did pretty detailed study through GDB there but 
I find that the illustration is lengthy to read. In this post, I try to show the same
concept using &lt;code&gt;char *&lt;/code&gt;. Hopefully, this time I do a better job.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#explanation"&gt;Explanation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;We are given the following program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// modify this function&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// modify here&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We want to implement &lt;code&gt;function()&lt;/code&gt; such that we can print out &lt;code&gt;Hello World!&lt;/code&gt; to the screen. The result of
the modification looks like below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// modify this function&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// modify here&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The question we want to answer is why doing so works?&lt;/p&gt;
&lt;h2 id="explanation"&gt;Explanation&lt;/h2&gt;
&lt;p&gt;We acquire key data from GDB as following:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GDB command&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x7fff5fbff360 ""&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p &amp;amp;s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(char **) 0x7fff5fbff340&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(char **) 0x7fff5fbff340&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p *c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x7fff5fbff360 ""&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(char **) 0x7fff5fbff340&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p *c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0x100000f8e "Hello World!"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Note that the last two commands are executed after &lt;code&gt;*c = "Hello World!";&lt;/code&gt;. The state of the variables on the stack shown below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="state of variables on the stack" class="img-responsive" src="https://zhu45.org/images/stack.png"/&gt;&lt;/p&gt;
&lt;p&gt;Note that one can think about &lt;em&gt;a variable in C as an alias for some virtual memory address&lt;/em&gt;. In other words, variable &lt;code&gt;s&lt;/code&gt; and address &lt;code&gt;0x7fff5fbff340&lt;/code&gt;
are the same thing and we use variable as a shortcut to reference some address. For a given variable name, we can get its address by using &lt;code&gt;&amp;amp;&lt;/code&gt;
(i.e., When &lt;code&gt;&amp;amp;&lt;/code&gt; used, the address of that variable is returned, instead of the variable itsef).
In our case, &lt;code&gt;&amp;amp;s&lt;/code&gt; is &lt;code&gt;0x7fff5fbff340&lt;/code&gt;. Since &lt;code&gt;s&lt;/code&gt; itself is a pointer, which by definition, contains a memory address instead of 
a value. In our case, the memory address in &lt;code&gt;s&lt;/code&gt; is &lt;code&gt;0x7fff5fbff360&lt;/code&gt;, which contains &lt;code&gt;""&lt;/code&gt; (note that &lt;code&gt;""&lt;/code&gt;
value is undefined. It could be any value).&lt;/p&gt;
&lt;p&gt;We pass &lt;code&gt;&amp;amp;s&lt;/code&gt; into the function because inside the function, if we modify the content on the address &lt;code&gt;0x7fff5fbff340&lt;/code&gt; (i.e. represented by &lt;code&gt;&amp;amp;s&lt;/code&gt;),
we can still reference &lt;code&gt;0x7fff5fbff340&lt;/code&gt; once the function exits. It’s because we can still access &lt;code&gt;s&lt;/code&gt;, and &lt;code&gt;s&lt;/code&gt; and &lt;code&gt;0x7fff5fbff340&lt;/code&gt; are the same thing.
Whatever change made to the content on &lt;code&gt;0x7fff5fbff340&lt;/code&gt; will be accessible by &lt;code&gt;s&lt;/code&gt; as well. 
Since &lt;code&gt;s&lt;/code&gt; has type &lt;code&gt;char*&lt;/code&gt;, then naturally &lt;code&gt;&amp;amp;s&lt;/code&gt; corresponds with type &lt;code&gt;char**&lt;/code&gt;. Another way of understanding
&lt;code&gt;char**&lt;/code&gt; is that we want to change the value of the passed in argument and C, by default, pass the argument
by copying the value. Thus, we need to pass in a pointer to that value, not just the value itself.&lt;/p&gt;
&lt;p&gt;Inside the function, we modify the content on the address &lt;code&gt;0x7fff5fbff340&lt;/code&gt; by deferencing &lt;code&gt;c&lt;/code&gt; (i.e. &lt;code&gt;*c&lt;/code&gt;), which holds a copy of &lt;code&gt;0x7fff5fbff340&lt;/code&gt;. 
After &lt;code&gt;*c = "Hello World!";&lt;/code&gt;, the content on the address &lt;code&gt;0x7fff5fbff340&lt;/code&gt; changed to &lt;code&gt;0x100000f8e&lt;/code&gt;, which contains &lt;code&gt;"Hello World!"&lt;/code&gt;. Once we are done
with the function and back to &lt;code&gt;main&lt;/code&gt;, since &lt;code&gt;s&lt;/code&gt; is the alias to &lt;code&gt;0x7fff5fbff340&lt;/code&gt; and &lt;code&gt;0x7fff5fbff340&lt;/code&gt; contains address to &lt;code&gt;"Hello World!"&lt;/code&gt;, our task
is accomplished.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;One thought I had when I finished this post was &lt;a href="https://stackoverflow.com/questions/52508492/why-cant-i-pass-the-pointer-instead-of-the-pointer-to-pointer-to-function"&gt;why can’t I pass &lt;code&gt;s&lt;/code&gt; instead of &lt;code&gt;&amp;amp;s&lt;/code&gt;&lt;/a&gt; because if &lt;code&gt;s&lt;/code&gt; contains some address
(say &lt;code&gt;0xab&lt;/code&gt;) and we modify the content on that address (&lt;code&gt;0xab&lt;/code&gt;) to be &lt;code&gt;"Hello World!"&lt;/code&gt;. Since &lt;code&gt;s&lt;/code&gt; contains It seems that there is another option we can use. 
However, &lt;a href="https://stackoverflow.com/questions/52508492/why-cant-i-pass-the-pointer-instead-of-the-pointer-to-pointer-to-function"&gt;as pointed out by others&lt;/a&gt;, the problem is that &lt;code&gt;s&lt;/code&gt; is uninitialized: whatever we do with the address contained in
&lt;code&gt;s&lt;/code&gt; is undefined behavior. Undefined behavior means there is no predictability of the program: anything can happen. Thus, even we can print out the string, we still consider doing so wrong.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Hope this short writeup helps!&lt;/p&gt;
&lt;p&gt;— 10/15/19 UPDATE —&lt;/p&gt;
&lt;p&gt;Addtional perspective to understand why &lt;code&gt;&amp;amp;s&lt;/code&gt; works: a pointer is just a regular variable that holds some memory address of 
another variable. Now, we want to instead of holding the memory address of some random content (e.g., &lt;code&gt;0x7fff5fbff360&lt;/code&gt;), hold 
the memory address of string &lt;code&gt;"Hello World!"&lt;/code&gt; (e.g., &lt;code&gt;0x100000f8e&lt;/code&gt;). A natural choice is to pass in the memory address of the variable that we want to modify the value it holds, which in this case is &lt;code&gt;&amp;amp;s&lt;/code&gt;.&lt;/p&gt;</content><category term="2018"></category><category term="c"></category></entry><entry><title>Graph basics + Topological Sort</title><link href="https://zhu45.org/posts/2018/Jul/14/graph-basics-topological-sort/" rel="alternate"></link><published>2018-07-14T22:30:00+08:00</published><updated>2018-07-14T22:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-07-14:/posts/2018/Jul/14/graph-basics-topological-sort/</id><summary type="html">&lt;p&gt;Basic graph concepts&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#graph-basics"&gt;Graph Basics&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#definitions"&gt;Definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#representation"&gt;Representation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#topological-sort"&gt;Topological Sort&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#definition-and-properties"&gt;Definition and Properties&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dfs-approach"&gt;DFS Approach&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#bfs-approach"&gt;BFS Approach&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In this post, we breifly summarize the basic concepts related to graph algorithm. Then, we study topological sort to make
the graph concepts into practice.&lt;/p&gt;
&lt;h2 id="graph-basics"&gt;Graph Basics&lt;/h2&gt;
&lt;h3 id="definitions"&gt;Definitions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;graph&lt;/strong&gt; &lt;span class="math"&gt;\(G = (V,E)\)&lt;/span&gt; consists of a set of &lt;strong&gt;vertices&lt;/strong&gt; &lt;span class="math"&gt;\(V\)&lt;/span&gt;, and a set of &lt;strong&gt;edges&lt;/strong&gt; &lt;span class="math"&gt;\(E\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Each edge (i.e., &lt;strong&gt;arcs&lt;/strong&gt;) is a pair &lt;span class="math"&gt;\((v,w)\)&lt;/span&gt;, where &lt;span class="math"&gt;\(v,w \in V\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Given an edge &lt;span class="math"&gt;\(e = (u,v)\)&lt;/span&gt;, the vertex &lt;span class="math"&gt;\(u\)&lt;/span&gt; is its &lt;strong&gt;source&lt;/strong&gt;, and &lt;span class="math"&gt;\(v\)&lt;/span&gt; is its &lt;strong&gt;sink&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If the pair is ordered, then the graph is &lt;strong&gt;directed&lt;/strong&gt; (i.e., &lt;strong&gt;digraphs&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Vertex &lt;span class="math"&gt;\(w\)&lt;/span&gt; is &lt;strong&gt;adjacent&lt;/strong&gt; to &lt;span class="math"&gt;\(v\)&lt;/span&gt; iff &lt;span class="math"&gt;\((v,w) \in E\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;In digraph, &lt;span class="math"&gt;\((v,w)\)&lt;/span&gt; is not the same as &lt;span class="math"&gt;\((w,v)\)&lt;/span&gt;. Thus, if &lt;span class="math"&gt;\((v,w) \in E\)&lt;/span&gt; and &lt;span class="math"&gt;\((w,v) \not\in E\)&lt;/span&gt;, &lt;span class="math"&gt;\(v\)&lt;/span&gt; is
adjacent to &lt;span class="math"&gt;\(w\)&lt;/span&gt; but &lt;span class="math"&gt;\(w\)&lt;/span&gt; is NOT adjacent to &lt;span class="math"&gt;\(v\)&lt;/span&gt;. However, for the undirected graph, if &lt;span class="math"&gt;\((v,w) \in E\)&lt;/span&gt;, then
&lt;span class="math"&gt;\((w,v) \in E\)&lt;/span&gt;. Thus, if &lt;span class="math"&gt;\(v\)&lt;/span&gt; is adjacent to &lt;span class="math"&gt;\(w\)&lt;/span&gt;, then &lt;span class="math"&gt;\(w\)&lt;/span&gt; is adjacent to &lt;span class="math"&gt;\(v\)&lt;/span&gt; in undirected graph.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;path&lt;/strong&gt; in a graph is a sequence of vertices &lt;span class="math"&gt;\(w_1, w_2, w_3, \dots, w_N\)&lt;/span&gt; such that &lt;span class="math"&gt;\((w_i, w_{i+1}) \in E\)&lt;/span&gt; for
&lt;span class="math"&gt;\(1 \le i &amp;lt; N\)&lt;/span&gt;. The &lt;strong&gt;length&lt;/strong&gt; of such path is the number of edges on the path, which is equal to &lt;span class="math"&gt;\(N - 1\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We allow a path from a vertex to itself&lt;ul&gt;
&lt;li&gt;If this path contains no edge, then the path length is 0&lt;/li&gt;
&lt;li&gt;If the graph contains an edge &lt;span class="math"&gt;\((v,v)\)&lt;/span&gt; from a vertex to itself, then the path &lt;span class="math"&gt;\(v,v\)&lt;/span&gt; is referred to as a &lt;strong&gt;loop&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;simple path&lt;/strong&gt; is a path such that all vertices are distinct, except that the first and last could be the same.&lt;/li&gt;
&lt;li&gt;If there is a path from &lt;span class="math"&gt;\(u\)&lt;/span&gt; to &lt;span class="math"&gt;\(v\)&lt;/span&gt;, &lt;span class="math"&gt;\(v\)&lt;/span&gt; is said to be &lt;strong&gt;reachable&lt;/strong&gt; from &lt;span class="math"&gt;\(u\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;cycle&lt;/strong&gt; in a graph:&lt;ul&gt;
&lt;li&gt;For directed graph, a cycle is a path of length at least 1 such that vertices &lt;span class="math"&gt;\(w_1 = w_N\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;For undirected graph, we require edges to be distinct&lt;ul&gt;
&lt;li&gt;reasoning: the path &lt;span class="math"&gt;\(u,v,u\)&lt;/span&gt; in an undirected graph should not be considered a cycle because &lt;span class="math"&gt;\((u,v)\)&lt;/span&gt; and &lt;span class="math"&gt;\((v,u)\)&lt;/span&gt;
are the same edge.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;directed acyclic graph (DAG)&lt;/strong&gt; is a directed graph in which there are no cycles (i.e., paths which contain one or
more edges and which begin and end at the same vertex)&lt;ul&gt;
&lt;li&gt;Vertices in a DAG which have no incoming edges are referred to as &lt;strong&gt;sources&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Vertices which have no outgoing edges are referred to as &lt;strong&gt;sinks&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;connected&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;An undirected graph is &lt;strong&gt;connected&lt;/strong&gt; if there is a path from every vertex to every other vertex.&lt;/li&gt;
&lt;li&gt;A directed graph is &lt;strong&gt;connected&lt;/strong&gt; if it contains a directed path from &lt;span class="math"&gt;\(u\)&lt;/span&gt; to &lt;span class="math"&gt;\(v\)&lt;/span&gt; or a directed path
from &lt;span class="math"&gt;\(v\)&lt;/span&gt; to &lt;span class="math"&gt;\(u\)&lt;/span&gt; for every pair of vertices &lt;span class="math"&gt;\(u\)&lt;/span&gt; and &lt;span class="math"&gt;\(v\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A directed graph is &lt;strong&gt;strongly connected&lt;/strong&gt; if it contains a directed path from &lt;span class="math"&gt;\(u\)&lt;/span&gt; to &lt;span class="math"&gt;\(v\)&lt;/span&gt; and a directed
path from &lt;span class="math"&gt;\(v\)&lt;/span&gt; to &lt;span class="math"&gt;\(u\)&lt;/span&gt; for every pair of vertices &lt;span class="math"&gt;\(u\)&lt;/span&gt; and &lt;span class="math"&gt;\(v\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;If a directed graph is not strongly connected, but the underlying graph (without direction to the arcs)
is connected, then the graph is said to be &lt;strong&gt;weakly connected&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;For a graph &lt;span class="math"&gt;\(G\)&lt;/span&gt;, a &lt;strong&gt;connected component&lt;/strong&gt; is a maximal set of vertices &lt;span class="math"&gt;\(C\)&lt;/span&gt; such that each pair of vertices in &lt;span class="math"&gt;\(C\)&lt;/span&gt; is connected
in &lt;span class="math"&gt;\(G\)&lt;/span&gt;. Every vertex belongs to exactly one connected component.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;complete graph&lt;/strong&gt; is a graph in which there is an edge between every pair of vertices.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;A tree is a special sort of graph - it is an undirected graph that is connected but has no cycles.
Given a graph &lt;span class="math"&gt;\(G = (V, E)\)&lt;/span&gt;, if the graph &lt;span class="math"&gt;\(G' = (V, E')\)&lt;/span&gt; where &lt;span class="math"&gt;\(E' \subset E\)&lt;/span&gt;, is a tree, then &lt;span class="math"&gt;\(G'\)&lt;/span&gt; is
referred to as a spanning tree of &lt;span class="math"&gt;\(G\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Indegree&lt;/strong&gt; of a vertex &lt;span class="math"&gt;\(v\)&lt;/span&gt; is the number of edges &lt;span class="math"&gt;\((u,v)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outdegree&lt;/strong&gt; of a vertex &lt;span class="math"&gt;\(v\)&lt;/span&gt; is the number of edges &lt;span class="math"&gt;\((v,u)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="representation"&gt;Representation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Adjacency matrix: use a &lt;span class="math"&gt;\(|V| \times |V|\)&lt;/span&gt; matrix indexed by vertices, with a &lt;code&gt;1&lt;/code&gt; indicating the presence of an edge (i.e.
For each edge &lt;span class="math"&gt;\((u, v)\)&lt;/span&gt;, we set &lt;code&gt;A[u][v]&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;; otherwise the entry in the array is &lt;code&gt;false&lt;/code&gt;). If the edge has a weight 
associated with it, then we can set &lt;code&gt;A[u][v]&lt;/code&gt; equal to the weight and use either a very large or 
a very small weight as a sentinel to indicate nonexistent edges.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Disadvantage: we require graph to be dense: &lt;span class="math"&gt;\(|E| = \Theta(|V|^2)\)&lt;/span&gt;, which is very unlikely.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Adjacency list: For each vertex, we keep a list of all adjacent vertices. For undirected graph, each edge &lt;span class="math"&gt;\((u,v)\)&lt;/span&gt; appears in
two lists&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Advantage: only requires &lt;span class="math"&gt;\(O(|E|+|V|)\)&lt;/span&gt; space.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edge Lists: we represent the graph as an array of &lt;span class="math"&gt;\(|E|\)&lt;/span&gt; edges. For example, for an undirected edge connects &lt;span class="math"&gt;\(0\)&lt;/span&gt; and &lt;span class="math"&gt;\(1\)&lt;/span&gt;, we can 
represent it as &lt;code&gt;[0,1]&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Checkout &lt;a href="https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs"&gt;Khan Academy::Computer Science::Algorithms::Representing graphs&lt;/a&gt; for a nice example.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="topological-sort"&gt;Topological Sort&lt;/h2&gt;
&lt;h3 id="definition-and-properties"&gt;Definition and Properties&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;We have following two equivalent definitions:&lt;ul&gt;
&lt;li&gt;Def 1: A topological sort is an ordering of vertices in a DAG such that
if there is a path from &lt;span class="math"&gt;\(v_i\)&lt;/span&gt; to &lt;span class="math"&gt;\(v_j\)&lt;/span&gt;, then &lt;span class="math"&gt;\(v_j\)&lt;/span&gt; appears
after &lt;span class="math"&gt;\(v_i\)&lt;/span&gt; in the ordering.&lt;/li&gt;
&lt;li&gt;Def 2: A topological ordering of a DAG &lt;span class="math"&gt;\(G\)&lt;/span&gt; is a labeling &lt;span class="math"&gt;\(f\)&lt;/span&gt; of 
&lt;span class="math"&gt;\(G\)&lt;/span&gt;‘s nodes such that:&lt;ul&gt;
&lt;li&gt;The &lt;span class="math"&gt;\(f(v)\)&lt;/span&gt;‘s are the set &lt;span class="math"&gt;\({1,2, \dots, n}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\((u,v) \in G \implies f(u) &amp;lt; f(v)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="topological sorting example" class="img-responsive" src="/images/topological-sort-example.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Application: sequence tasks while respecting all precedence constraints.
(e.g. course prerequisite structure can be represented as a graph. A topological ordering of these courses is any course sequence that does not violate the prerequisite requirement.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If G has a cycle, there is no topological sort: since for two vertices &lt;span class="math"&gt;\(v\)&lt;/span&gt; and &lt;span class="math"&gt;\(w\)&lt;/span&gt; on the cycle, &lt;span class="math"&gt;\(v\)&lt;/span&gt; precedes &lt;span class="math"&gt;\(w\)&lt;/span&gt; and &lt;span class="math"&gt;\(w\)&lt;/span&gt; precedes &lt;span class="math"&gt;\(v\)&lt;/span&gt;. On ther other hand,
if there is no directed cycle in the graph, we can compute topological sort in linear time (&lt;span class="math"&gt;\(O(|V|+|E|)\)&lt;/span&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Topological sorting is not necessary unique as shown in the picture above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="dfs-approach"&gt;DFS Approach&lt;/h3&gt;
&lt;p&gt;The basic idea of computing the topological ordering is following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let &lt;span class="math"&gt;\(v\)&lt;/span&gt; be a sink vertex of &lt;span class="math"&gt;\(G\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;set &lt;span class="math"&gt;\(f(v) = n\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;recurse on &lt;span class="math"&gt;\(G - {v}\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some proofs we need to show for the correctness of the procedure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Every directed acyclic graph has a sink vertex&lt;/p&gt;
&lt;p&gt;Suppose the DAG doesn’t have a sink vertex, that means every single vertex has at least one outgoing arc. We can start with arbitrary
vertex and follow its outgoing arc to the next vertex. Since there is no sink vertex in our graph, we can repeatedly follow the outgoing
arc of the vertex. Suppose there are &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes in the graph and by following edges for &lt;span class="math"&gt;\(N\)&lt;/span&gt; times, we reach the &lt;span class="math"&gt;\(N+1\)&lt;/span&gt;th vertex. Since among
the &lt;span class="math"&gt;\(N+1\)&lt;/span&gt; nodes, there are only &lt;span class="math"&gt;\(N\)&lt;/span&gt; distinct nodes. By the pigeonhole principle, we must have visted some vertex twice. By following the
nodes and visited some node twice, we show that the graph contains a directed cycle, which is a contradiction.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;During each recursion step, we can find a sink vertex&lt;/p&gt;
&lt;p&gt;For a DAG, if we delete one or some of the vertices, we still have DAG (i.e., we cannot create a directed cycle). Thus,
in each recursion step, we always have DAG. Then, by the previous observation, during each recursion step, we can find a sink vertex.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The above steps do produce topological ordering&lt;/p&gt;
&lt;p&gt;By topological ordering, we know that all the edges have to go forward. Intutively, we always want to assign the sink vertex
of the graph to the final position because otherwise there is going to be an outgoing arc of the node and the node that the
outgoing arc points to will be assigned a lower position, which violates the topological ordering (i.e. edge goes backward). 
In our procedure, when a node &lt;span class="math"&gt;\(v\)&lt;/span&gt; is assigned to position &lt;span class="math"&gt;\(i\)&lt;/span&gt;, that means we only have &lt;span class="math"&gt;\(i\)&lt;/span&gt; nodes remaining and &lt;span class="math"&gt;\(v\)&lt;/span&gt; is the sink vertex. 
This implies that all of outgoing arcs and the corresponding nodes are deleted and assigned higher positions. So for every vertex, 
by the time it actually gets assigned a position, it’s a sink and it only has incoming arcs from the as yet unsigned vertices. 
It’s outgoing arcs all go forward to vertices that were already assigned higher positions, and got deleted previously from the graph. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To implement the procedure above, we use the DFS:&lt;/p&gt;
&lt;p&gt;&lt;img alt="DFS for topological sort" class="img-responsive" src="/images/topological-dfs.png"/&gt;&lt;/p&gt;
&lt;p&gt;There are several points we need to note here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We set &lt;span class="math"&gt;\(f(s) = \text{current_label}\)&lt;/span&gt; right before we about to pop the call stack. At that point, for every edge &lt;span class="math"&gt;\((s,v)\)&lt;/span&gt;, there is no such
&lt;span class="math"&gt;\(v\)&lt;/span&gt; that we haven’t explored. That means there are no outgoing edges, which indicate that &lt;span class="math"&gt;\(s\)&lt;/span&gt; is a sink and thus we can assign it a labeling.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Running time: &lt;span class="math"&gt;\(O(|E|+|V|)\)&lt;/span&gt; (we only visit each vertex in the graph once and we look at each edge once as well)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Correctness: we want to show that this DFS algorithm can correctly produce topological ordering. Topological ordering requires that for
an edge &lt;span class="math"&gt;\((s,v)\)&lt;/span&gt;, &lt;span class="math"&gt;\(f(s) &amp;lt; f(v)\)&lt;/span&gt;. There are two possible cases for DFS: 1) &lt;span class="math"&gt;\(s\)&lt;/span&gt; get visited first 2) &lt;span class="math"&gt;\(v\)&lt;/span&gt; get visited first. For the first case,
since there is an edge from &lt;span class="math"&gt;\(s\)&lt;/span&gt; to &lt;span class="math"&gt;\(v\)&lt;/span&gt;, DFS will recursively call on &lt;span class="math"&gt;\(v\)&lt;/span&gt;. In other words, DFS call on &lt;span class="math"&gt;\(v\)&lt;/span&gt; will finish before the DFS call on &lt;span class="math"&gt;\(s\)&lt;/span&gt;.
Thus, &lt;span class="math"&gt;\(v\)&lt;/span&gt; will get a label larger than &lt;span class="math"&gt;\(s\)&lt;/span&gt; and the topological ordering is satisfied. For the second case, since there is no cycle in DAG, &lt;span class="math"&gt;\(s\)&lt;/span&gt; will
not get discovered. Thus, &lt;span class="math"&gt;\(s\)&lt;/span&gt; will be visited later than &lt;span class="math"&gt;\(v\)&lt;/span&gt;. By the same reasoning as the first case, we still have the topological ordering.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="bfs-approach"&gt;BFS Approach&lt;/h3&gt;
&lt;p&gt;Not surprisingly, we can find topological ordering of a graph using BFS as well. Instead of finding the sink vertex each time (i.e. the vertex
with outdegree = 0), we find the source vertex (i.e. the vertex with indegree = 0) each time in BFS. The basic steps to compute the topological ordering follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let &lt;span class="math"&gt;\(s\)&lt;/span&gt; be a source vertex of &lt;span class="math"&gt;\(G\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;set &lt;span class="math"&gt;\(f(s) = 1\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;recurse on &lt;span class="math"&gt;\(G - {s}\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We omit the proofs of the properties in BFS as the proofs will mirror with the ones for DFS. We can use the BFS to implement the procedure above:&lt;/p&gt;
&lt;p&gt;&lt;img alt="DFS for topological sort" class="img-responsive" src="/images/topological-bfs.png"/&gt;&lt;/p&gt;
&lt;p&gt;There are several points we need to note here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the basic version, we pick a source vertex of &lt;span class="math"&gt;\(G\)&lt;/span&gt; each time and assign the label. Inevitably, we will compute all the indegree of all nodes in
the graph to find the source vertices. However, not all nodes’ indegrees will be updated. To save this duplicate calculation, we use a queue (box).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Running time: &lt;span class="math"&gt;\(O(|E|+|V|)\)&lt;/span&gt; (We visit each edge once and for each node, we visit twice: compute the inital indegree; assign the labeling)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Correctness: this BFS will prodcue the topological ordering because for an edge &lt;span class="math"&gt;\((s,v)\)&lt;/span&gt;, we will always visit &lt;span class="math"&gt;\(s\)&lt;/span&gt; before visiting &lt;span class="math"&gt;\(v\)&lt;/span&gt;. Without
removing &lt;span class="math"&gt;\(s\)&lt;/span&gt; first, &lt;span class="math"&gt;\(v\)&lt;/span&gt; will always have an incoming edge, which will not make &lt;span class="math"&gt;\(v\)&lt;/span&gt; a source vertex. Since we assign the labeling in the increasing order,
&lt;span class="math"&gt;\(f(s) &amp;lt; f(v)\)&lt;/span&gt;. Thus, we produce a topological ordering.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As one can see the difference between DFS and BFS is that: for DFS, we start with the sink vertex and assign the label of the vertices in the decreasing
order (i.e. start from &lt;span class="math"&gt;\(n\)&lt;/span&gt; and until &lt;span class="math"&gt;\(1\)&lt;/span&gt;). However, for BFS, we start with the source vertex and assign the label of the vertices in the increasing fashion
(i.e. start from &lt;span class="math"&gt;\(1\)&lt;/span&gt; and until &lt;span class="math"&gt;\(n\)&lt;/span&gt;).&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;“Data Structures and Algorithm Analysis in C++, 4th Edition” by Mark A. Weiss (we use
&lt;em&gt;MAW (cpp)&lt;/em&gt; for short in the future)&lt;/li&gt;
&lt;li&gt;“Elements of Programming Interviews: The Insiders’ Guide” by Adnan Aziz,
Tsung-Hsien Lee, and Amit Prakash, p.342 - 346 (we use &lt;em&gt;ATA&lt;/em&gt; for short in the future)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.coursera.org/learn/algorithms-graphs-data-structures/lecture/yeKm7/topological-sort"&gt;Topological Sort on Coursera&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2018"></category><category term="graph"></category><category term="sorting"></category><category term="maw"></category></entry><entry><title>Flash-based SSD Basics</title><link href="https://zhu45.org/posts/2018/Jul/01/flash-based-ssd-basics/" rel="alternate"></link><published>2018-07-01T22:00:00+08:00</published><updated>2018-07-01T22:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-07-01:/posts/2018/Jul/01/flash-based-ssd-basics/</id><summary type="html">&lt;p&gt;list out the basic concepts in SSD&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#raw-flash"&gt;Raw Flash&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#storing-a-single-bit"&gt;Storing a Single Bit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#from-bits-to-banksplanes"&gt;From Bits to Banks/Planes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#basic-flash-operations"&gt;Basic Flash Operations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#flash-performance-and-reliability"&gt;Flash Performance and Reliability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#from-raw-flash-to-flash-based-ssds"&gt;From Raw Flash to Flash-Based SSDs&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#the-organization-of-flash-based-ssd"&gt;The organization of Flash-based SSD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#build-flash-translation-layer-ftl"&gt;Build Flash Translation Layer (FTL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#flash-based-ssd-performance"&gt;Flash-based SSD performance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#summary"&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In this post, we highlight the key points from &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-ssd.pdf"&gt;Chapter 44: Flash-based SSDs from OSTEP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Solid-state storage device (SSD) is built out of transistors (like memory and processors) but it can retain information without power. First, we introduce the physical properties of the raw flash. Then, we focus on building a persistent storage device (i.e. NAND-based flash-based SSD)based on those physical properties.&lt;/p&gt;
&lt;p&gt;Please note that I organize the post based on my own understanding of the chapter: the organization may not reflect the actual organization of the chapter. 
I also add a few illustrations to reflect the concepts in the chapter. Black &amp;amp; white pictures are taken from the book while the color ones are the drawings on my own.&lt;/p&gt;
&lt;h2 id="raw-flash"&gt;Raw Flash&lt;/h2&gt;
&lt;p&gt;In this section, we introduce the raw flash using the bottom-up approach by first introducing the basic building block: transistor (i.e. cell). Then,
we organize those cells into flash planes, which consist of physical blocks and pages. Finally, we introduce the basic operations supported
by the raw flash and possible performance and reliability considerations when we build a persistent storage device.&lt;/p&gt;
&lt;h3 id="storing-a-single-bit"&gt;Storing a Single Bit&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Single-level cell (SLC) flash: a transistor (cell) stores a single bit (1 or 0)&lt;/li&gt;
&lt;li&gt;Multi-level cell (MLC) flash: a transistor (cell) stores two bits (00, 01, 10,11)&lt;/li&gt;
&lt;li&gt;Triple-level cell (TLC) flash: a transistor (cell) encodes 3 bits.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="from-bits-to-banksplanes"&gt;From Bits to Banks/Planes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Flash chips are organized into &lt;strong&gt;banks&lt;/strong&gt; or &lt;strong&gt;planes&lt;/strong&gt;, which consists
of a large number of cells. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="A flash plane" class="img-responsive" src="/images/ssd.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;strong&gt;bank&lt;/strong&gt; (&lt;strong&gt;plane&lt;/strong&gt;) is accessed in two different sized units:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;blocks&lt;/strong&gt; (&lt;strong&gt;erase blocks&lt;/strong&gt;): 128KB or 256KB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pages&lt;/strong&gt;: 4KB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="basic-flash-operations"&gt;Basic Flash Operations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Three low-level flash chip operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Read (a page)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;read any page by specifying page number&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;random access&lt;/strong&gt; device: being able to access any location uniformly quickly (regardless of location on the device and the location of previous request)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Erase (a block)&lt;/strong&gt;: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before writing to a page within a flash, the device needs to first erase the entire block the page within&lt;/li&gt;
&lt;li&gt;Need to make sure we save the contents of the to-be-erased blocks before executing the erase&lt;/li&gt;
&lt;li&gt;The entire block is reset and each page within is read to be programmed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Program (a page)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Modified the page and write the modification to flash&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Three flash operation demonstrations" class="img-responsive" src="/images/read-erase-program.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;We use &lt;span class="math"&gt;\(\texttt{INVALID}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\texttt{ERASED}\)&lt;/span&gt;, and &lt;span class="math"&gt;\(\texttt{VALID}\)&lt;/span&gt;
to represents three states of a page. One should note that write to a page with state &lt;span class="math"&gt;\(\texttt{E}\)&lt;/span&gt; doesn’t cause the entire block to be erased.
However, to write to a page with state &lt;span class="math"&gt;\(\texttt{V}\)&lt;/span&gt;, the device requires
the whole block to be erased.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="Raw Flash Performance" class="img-responsive" src="/images/raw-flash-performance.png"/&gt;&lt;/p&gt;
&lt;h3 id="flash-performance-and-reliability"&gt;Flash Performance and Reliability&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;wear out&lt;/strong&gt;: when a flash block is erased and programmed, it slowly
accures a little bit of extra charge. Over time, as that extra charge
builds up, it becomes increasingly diffcult to differentiate between a 0
and a 1. At the point where it becomes impossible, the block becomes unusable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;disturbance&lt;/strong&gt;: when accessing a particular page within a flash, it
is possible that some bits get flipped in neighboring pages; such bit
flips are known as &lt;strong&gt;read disturbs&lt;/strong&gt; or &lt;strong&gt;program disturbs&lt;/strong&gt;, depending
on whether the page is being read or programmed, respectively.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="from-raw-flash-to-flash-based-ssds"&gt;From Raw Flash to Flash-Based SSDs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Goal: standard storage interface is bocked-based one, where blocks
(sectors) of size 512 bytes can be read or written, given a block address.
Thus, flash-based SSD is to provide that standard block interface
atop the raw flash chips inside it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="the-organization-of-flash-based-ssd"&gt;The organization of Flash-based SSD&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SSD consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flash chips: for persistent storage &lt;/li&gt;
&lt;li&gt;Volatile memory (SRAM): caching, buffering data, mapping tables&lt;/li&gt;
&lt;li&gt;Control logic (FTL)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="SSD structure" class="img-responsive" src="/images/ssd-structure.png"/&gt;&lt;/p&gt;
&lt;h3 id="build-flash-translation-layer-ftl"&gt;Build Flash Translation Layer (FTL)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Flash Translation Layer (FTL):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Translate client reads &amp;amp; writes on logical blocks -&amp;gt; flash read, erase, program on physical blocks &amp;amp; pages&lt;/li&gt;
&lt;li&gt;performance:&lt;ul&gt;
&lt;li&gt;Use multiple flash chips in parallel&lt;/li&gt;
&lt;li&gt;Reduce write amplification: the total write traffic (in bytes) issued to the flash chips by the FTL divided by the total write traffic (in bytes) issued by the client to the SSD.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;reliability:&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;wear leveling&lt;/strong&gt; (prevent wear out): spread writes across the blocks of the flash as evenly as possible, ensuring that all of the blocks of the device wear out at roughly the same time;&lt;/li&gt;
&lt;li&gt;Prevent disturbance: program pages within an erased block &lt;em&gt;in order&lt;/em&gt;, from low page to high page&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Direct-mapped FTL:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1-1 mapping between logic page and physical page&lt;ul&gt;
&lt;li&gt;Read of a logical page &lt;span class="math"&gt;\(N\)&lt;/span&gt; mapped to read of a physical page &lt;span class="math"&gt;\(N\)&lt;/span&gt;
directly&lt;/li&gt;
&lt;li&gt;Overwrtie of a logical page &lt;span class="math"&gt;\(N\)&lt;/span&gt; leads to the write amplification:&lt;ul&gt;
&lt;li&gt;Read in the entire block that contains physical page &lt;span class="math"&gt;\(N\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Erase the block&lt;/li&gt;
&lt;li&gt;Program the page &lt;span class="math"&gt;\(N\)&lt;/span&gt; along with the old pages within the block&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Can lead to wear out if the user repeated update the same logical 
page (e.g., update the same file system metadata over and over)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Log-structured FTL:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Upon a write to a logical block &lt;span class="math"&gt;\(N\)&lt;/span&gt;, the device appends the write
to the the next free spot in the currently-being-written-to block.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write: the SSD finds a location for the write, usually just picking
the next free page; it then programs that page with the block’s contents, and records the logical-to-physical mapping in its mapping
table.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read: subsequent reads use the table to translate the logical block
address presented by the client into the physical page number required to read the data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Advantages: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We avoid the overwrite of the physical page (by always writing to the next free page), which can cause the expensive erase
operation and write amplification.&lt;/li&gt;
&lt;li&gt;FTL spreads the write across all pages and perform wear leveling
to increase the lifetime of the device.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Disadvantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need to periodically perform garbage collection, which can increase write amplification and reduce performance&lt;/li&gt;
&lt;li&gt;High cost of in-memory mapping tables (the larger the device,
the more memory such tables need)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;crash recovery:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Since mapping table is stored in memory, we may lose it when
device loses power. To handle this, we can store some mapping
information in &lt;strong&gt;out-of-band (OOB)&lt;/strong&gt; area within each page and
reconstruct the mapping table in memory.&lt;/li&gt;
&lt;li&gt;Use logging and checking to speed up recovery.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="log-structured FTL" class="img-responsive" src="/images/log-structured-ftl.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Garbage Collection (dead-block reclamation):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Garbage: old versions of data around the drive that takes up the space&lt;ul&gt;
&lt;li&gt;Ex: immediately follow the picture above, we write(100) with
content “c1”. The original “a1” is no longer needed, which is considered as garbage. We need to reclaim the physical page that
“a1” takes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Garbage collection: the process of finding garbage blocks and
reclaiming them for future use. We can find a block that contains
one or more garbage pages, read in the live (non-garbage) pages from
that block, write out those live pages to the log, and (finally)
reclaim the entire block for use in writing.&lt;/li&gt;
&lt;li&gt;Determine the dead pages: the physical block contains the logical
block addresses it is holding. We can then determine the dead pages by comparing the logical block addresses in the mapping table with the logical block addresses in the physical block (e.g., physical block holds logical block address 2000 but 2000 inside the mapping
table pointing to the physical page that is outside of the current
physical block. Thus, we know the physical page that holds 2000
inside the physical block is the dead page).&lt;/li&gt;
&lt;li&gt;The ideal candidate for reclamation is a block that consists of
only dead pages; in this case, the block can immediately be erased
and used for new data, without expensive data migration.&lt;/li&gt;
&lt;li&gt;Reduce GC costs: &lt;strong&gt;overprovision&lt;/strong&gt; the device (adding extra
flash capacity)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Block-Based Mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instead of keeping one record per page in the mapping table, we keep
one record per block. Doing so will reduce the size of mapping table by a factor of &lt;span class="math"&gt;\(\frac{Size_{block}}{Size_{page}}\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Read: The read of a logical block address is shown in picture below. The whole read process greatly mimics the virtual address translation. The mapping table plays a role as the page table in the virtual memory system (map virtual pages to physical frames).&lt;/li&gt;
&lt;li&gt;Write: if the client writes to logical block 2002 with content &lt;span class="math"&gt;\(c'\)&lt;/span&gt;,
since by the current mapping, we try to overwrite the physical page with new content, FTL has to perform erase. FTL will read in 2000, 2001, and 2003 and then write out all four
logical blocks in a new location (e.g. physical pages 08,09,10,11 with values a, b, c’, d), updating the mapping table accordingly and
erase the original block. We can transfer the a,b,c’,d back to the original block but that will involve another set of writes, which are
expensive compared with updating the mapping table record.&lt;/li&gt;
&lt;li&gt;Disadvantage: performance decrease for the writes smaller than
the physical block size of the device (If the writes equal to
the physical block size, we can erase the whole block and do write
directly instead of saving some old data and rewrite them again
into new location.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="block-based read process" class="img-responsive" src="/images/block-based-mapping-ftl.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hybrid Mapping&lt;ul&gt;
&lt;li&gt;Combine the page-level mapping (enable flexible writing) + block-level mapping (reduce mapping costs)&lt;/li&gt;
&lt;li&gt;FTL structure is shown in the picture below.&lt;/li&gt;
&lt;li&gt;One big challenge in the hyprid mapping FTL is the “compaction”, which means we have to move the contents from
log blocks referred by the log table into the physical blocks referred by the data table. The motivation is that
we want to keep the size of log table small (i.e. reduce mapping costs). There are three ways
we can perform depends on the contents of the blocks: &lt;strong&gt;switch merge&lt;/strong&gt;, &lt;strong&gt;partial merge&lt;/strong&gt;, &lt;strong&gt;full merge&lt;/strong&gt; shown
in the picture below.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="hybrid mapping FTL" class="img-responsive" src="/images/hybrid-mapping.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="merge in hybrid mapping FTL" class="img-responsive" src="/images/merge-in-hybrid-mapping.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;“compaction” isn’t a term used in the chapter. I use the term as a way to indicate the whole moving log block
process greatly mimics how the compaction works in the &lt;a href="https://zhu45.org/posts/2018/Mar/30/pebblesdb-building-key-value-stores-using-fragmented-log-structured-merge-trees/"&gt;Log-structured merge (LSM) tree&lt;/a&gt;.
Log blocks can be thought of as “memtable” in the LSM-based key-value store. In addition, when we look for a 
particular logical block, the FTL will first consult the log table; if the logical block’s location is not found there, 
the FTL will then consult the data table to find its location and then access the requested data. Also, we need to periodically
scan the log table and corresponding log blocks to form blocks pointed by only one block pointer. All these behaviors
are similar to how read and compaction work in the LSM-based key-value store.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;wear leveling&lt;ul&gt;
&lt;li&gt;Log-structured approach + garbage collection helps with the wear leveling&lt;/li&gt;
&lt;li&gt;Problem: sometimes a block will be filled with long-lived data that does not get overwritten; in this case, garbage collection will never reclaim the block, and thus it does not receive its fair share of the write load.&lt;/li&gt;
&lt;li&gt;Solution: the FTL must periodically read all the live data out of such blocks and re-write it elsewhere, thus making the block available for writing again.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="flash-based-ssd-performance"&gt;Flash-based SSD performance&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The biggest difference in performance, as compared to disk drives, is realized when performing random reads and writes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="SSD vs. HDD performance" class="img-responsive" src="/images/SSD-HDD.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Findings in the above table:&lt;ul&gt;
&lt;li&gt;SSD random I/O outperforms HDD random I/O&lt;/li&gt;
&lt;li&gt;SSD sequential I/O is slightly above HDD sequential I/O (i.e. HDD still in the game for the sequential I/O task)&lt;/li&gt;
&lt;li&gt;SSD random write beat random read&lt;ul&gt;
&lt;li&gt;log-structured design of many SSDs, which transforms random writes into sequential ones and improves performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HDD is still cheaper than SSD&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Overwriting a page requires us to erase the whole block that the page resides in before we can write the page. This naturally introduces the
write amplification as we must first move any data we care about to another location.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When design a persistent storage device based on flash, we need to think about performance (e.g. write amplification) and reliability
(e.g. wear out, disturbance).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Log-structured hybrid mapping FTL provides an interface that maps the I/O to logical address space to the physical blocks &amp;amp; pages on the flash chips
while maintaining good performance and reliability.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2018"></category><category term="ssd"></category><category term="storage"></category><category term="ostep"></category></entry><entry><title>Generalized binary search</title><link href="https://zhu45.org/posts/2018/Jun/10/generalized-binary-search/" rel="alternate"></link><published>2018-06-10T01:24:00+08:00</published><updated>2018-06-10T01:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-06-10:/posts/2018/Jun/10/generalized-binary-search/</id><summary type="html">&lt;p&gt;Binary search idea can be generalized to other problems&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#example"&gt;Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the &lt;a href="https://zhu45.org/posts/2018/Jan/12/how-to-write-binary-search-correctly/"&gt;earlier post&lt;/a&gt;, we introduce the invariant concept to enable us
to solve the binary search problem on the very first try. In this post, we further elaborate the binary
search idea and introduce how we can use predicate + main theorem to solve more generalized binary search problem.&lt;/p&gt;
&lt;h2 id="example"&gt;Example&lt;/h2&gt;
&lt;p&gt;Let’s consider an example, which utilizes the generalized idea of binary search mentioned in &lt;a href="https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/"&gt;TopCoder’s article&lt;/a&gt;. The problem we look at is 
&lt;a href="https://leetcode.com/problems/find-k-closest-elements/description/"&gt;Leetcode 658. Find K Closest Elements&lt;/a&gt;: 
Let &lt;span class="math"&gt;\(A\)&lt;/span&gt; be a sorted array of &lt;span class="math"&gt;\(N\)&lt;/span&gt; values. We want to find the index &lt;span class="math"&gt;\(j\)&lt;/span&gt; such that the elements &lt;span class="math"&gt;\(A_j,A_{j+1},\dots,A_{j+k−1}\)&lt;/span&gt; 
have the &lt;span class="math"&gt;\(k\)&lt;/span&gt; closest values to the given target value &lt;span class="math"&gt;\(T\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;The generalization of binary search is done by formalizing how we reduce the search space by half: binary search can be used
if and only if for all &lt;span class="math"&gt;\(x\)&lt;/span&gt; in the search space &lt;span class="math"&gt;\(S\)&lt;/span&gt; (i.e., the ordered set), &lt;span class="math"&gt;\(p(x)\)&lt;/span&gt; implies &lt;span class="math"&gt;\(p(y)\)&lt;/span&gt; for all &lt;span class="math"&gt;\(y &amp;gt; x\)&lt;/span&gt; (&lt;span class="math"&gt;\(p\)&lt;/span&gt; stands
for some predicate over &lt;span class="math"&gt;\(S\)&lt;/span&gt;). TopCoder article calls this formalization as &lt;em&gt;main theorem&lt;/em&gt;. We use this theorem to discard
the second half of search space. For example, in the most basic binary search problem in the ascending order array, our predicate &lt;span class="math"&gt;\(p\)&lt;/span&gt; 
is defined as: is the value at &lt;code&gt;i&lt;/code&gt; smaller than &lt;code&gt;X&lt;/code&gt;? If answer is yes, we discard all the values 
with index smaller than &lt;span class="math"&gt;\(i\)&lt;/span&gt; because given the ascending order and &lt;code&gt;A[i]&lt;/code&gt; is smaller than &lt;code&gt;X&lt;/code&gt;, any value comes before &lt;code&gt;A[i]&lt;/code&gt; is also 
smaller than &lt;code&gt;X&lt;/code&gt;. By the same reasoning, if the answer is no, we discard the second half. We make some observations here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As you may have noticed, predicate is exactly what we check in the if-statement (e.g. &lt;code&gt;X &amp;gt; A[i]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;X &amp;lt; A[i]&lt;/code&gt;, then for any &lt;span class="math"&gt;\(y &amp;gt; i\)&lt;/span&gt;, we have &lt;code&gt;X &amp;lt; A[y]&lt;/code&gt;, which exactly matches the main theorem and that’s how we can discard
the second half of the array (i.e., search space).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, let’s consider our example. What does it mean a selected subrange is optimal (i.e., &lt;span class="math"&gt;\(k\)&lt;/span&gt; closest values to &lt;span class="math"&gt;\(T\)&lt;/span&gt;)? That means
that we can neither move the subrange to the right (&lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt;) nor move the subrange to the left 
(&lt;span class="math"&gt;\(|A_{j+k-1} - T| &amp;gt; |A_{j-1} - T|\)&lt;/span&gt;). In details, since the subrange includes &lt;span class="math"&gt;\(k\)&lt;/span&gt; closest values to &lt;span class="math"&gt;\(T\)&lt;/span&gt; and by moving it to right,
we exclude &lt;span class="math"&gt;\(A_{j}\)&lt;/span&gt; and include &lt;span class="math"&gt;\(A_{j+k}\)&lt;/span&gt;. Since the selected subrange is optimal, we must have &lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt;.
Thus, we can formalize our predicate as: for a given index &lt;span class="math"&gt;\(j\)&lt;/span&gt;, does &lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt; hold? Another piece of information
we need for binary search is the invariant. From the question description we can see that the key to this question is finding
&lt;span class="math"&gt;\(j\)&lt;/span&gt;. Thus, our invariant is: the index of the first number that is among the k closest values for the given target &lt;span class="math"&gt;\(T\)&lt;/span&gt; 
(i.e., &lt;span class="math"&gt;\(j\)&lt;/span&gt;) is in &lt;span class="math"&gt;\([\text{left}, \text{right}]\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Now, we have to show that &lt;em&gt;main theorem&lt;/em&gt; holds given our predicate formalization. Let’s discuss this point
in details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When &lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt; is true:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(A\)&lt;/span&gt; is sorted in ascending order, then we have three possible cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(T &amp;lt; A_j &amp;lt; A_{j+k}\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(A_{j+k} - T &amp;gt; A_j - T\)&lt;/span&gt;. Let &lt;span class="math"&gt;\(d\)&lt;/span&gt; be an integer with range
&lt;span class="math"&gt;\(0 &amp;lt; d &amp;lt; k\)&lt;/span&gt;, then we have
&lt;span class="math"&gt;\(A_{j+k+d} - T &amp;gt; A_{j+k} - T &amp;gt; A_{j+d} - T &amp;gt; A_{j} - T\)&lt;/span&gt;. In other words, for any index &lt;span class="math"&gt;\(i &amp;gt; j\)&lt;/span&gt;, our predicate
holds (&lt;span class="math"&gt;\(|A_{i+k} - T| &amp;gt; |A_i - T|\)&lt;/span&gt;). Thus, we can directly discard the second half of the array. Note that
we still want to keep &lt;span class="math"&gt;\(j\)&lt;/span&gt; because it might be the optimal &lt;span class="math"&gt;\(j\)&lt;/span&gt; we are looking for.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_j &amp;lt; T &amp;lt; A_{j+k}\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(A_{j+k} - T &amp;gt; T - A_j\)&lt;/span&gt;. Then, we have 
&lt;span class="math"&gt;\(A_{j+k+d} - T &amp;gt; A_{j+k} - T &amp;gt; T - A_j &amp;gt; T - A_{j+d}\)&lt;/span&gt;. Then the predicate still holds for &lt;span class="math"&gt;\(i &amp;gt; j\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_j &amp;lt; A_{j+k} &amp;lt; T\)&lt;/span&gt;. This is impossible given our predicate condition.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(A\)&lt;/span&gt; is sorted in descending order, we also have three possible cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(T &amp;gt; A_j &amp;gt; A_{j+k}\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(T - A_{j+k} &amp;gt; T - A_j\)&lt;/span&gt;, which leads to 
&lt;span class="math"&gt;\(T - A_{j+k+d} &amp;gt; T - A_{j+k} &amp;gt; T - A_{j+d} &amp;gt; T - A_j\)&lt;/span&gt;. Again, our predicate holds for any index &lt;span class="math"&gt;\(i &amp;gt; j\)&lt;/span&gt; and
we can discard the second half of the array.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_j &amp;gt; T &amp;gt; A_{j+k}\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(T - A_{j+k} &amp;gt; A_j - T\)&lt;/span&gt;. We have
&lt;span class="math"&gt;\(T - A_{j+k+d} &amp;gt; T - A_{j+k} &amp;gt; A_j - T &amp;gt; A_{j+d} - T\)&lt;/span&gt;. Predicate holds.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_j &amp;gt; A_{j+k} &amp;gt; T\)&lt;/span&gt;. Impossible.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The reason we have &lt;span class="math"&gt;\(0 \le d \le k\)&lt;/span&gt; is that in the extreme case, we have &lt;span class="math"&gt;\(j = N - k\)&lt;/span&gt; (otherwise, we won’t have &lt;span class="math"&gt;\(k\)&lt;/span&gt; elements)
and it is unnecessary to have &lt;span class="math"&gt;\(d\)&lt;/span&gt; goes beyond &lt;span class="math"&gt;\(k\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When &lt;span class="math"&gt;\(|A_{j-1} - T| &amp;gt; |A_{j+k-1} - T|\)&lt;/span&gt; is true:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(A\)&lt;/span&gt; is sorted in ascending order, then we have three possible cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(T &amp;lt; A_{j-1} &amp;lt; A_{j+k-1}\)&lt;/span&gt;. Impossible.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_{j-1} &amp;lt; T &amp;lt; A_{j+k-1}\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(T - A_{j-1} &amp;gt; A_{j+k-1} - T\)&lt;/span&gt;. Then, let &lt;span class="math"&gt;\(d\)&lt;/span&gt; be an integer with
range between 0 and &lt;span class="math"&gt;\(j-1\)&lt;/span&gt;. We have &lt;span class="math"&gt;\(T - A_{j-1-d} &amp;gt; T - A_{j-1} &amp;gt; A_{j+k-1} - T &amp;gt; A_{j+k-1-d} - T\)&lt;/span&gt;. Thus, for any
index &lt;span class="math"&gt;\(i &amp;lt;= j\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(|A_{i-1} - T| &amp;gt; |A_{i+k-1} - T|\)&lt;/span&gt;. This suggests that we can discard first half of the array.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_{j-1} &amp;lt; A_{j+k-1} &amp;lt; T\)&lt;/span&gt;. We have &lt;span class="math"&gt;\(T - A_{j-1} &amp;gt; T - A_{j+k-1}\)&lt;/span&gt;, which implies 
&lt;span class="math"&gt;\(T - A_{j-1-d} &amp;gt; T - A_{j-1} &amp;gt; T - A_{j+k-1-d} &amp;gt; T - A_{j+k-1}\)&lt;/span&gt;, which again the predicate holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(A\)&lt;/span&gt; is sorted in descending order, then we have three possible cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(T &amp;gt; A_j &amp;gt; A_{j+k}\)&lt;/span&gt;. Impossible.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_j &amp;gt; T &amp;gt; A_{j+k}\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(A_{j-1} - T &amp;gt; T - A_{j+k-1}\)&lt;/span&gt;, which implies that 
&lt;span class="math"&gt;\(A_{j-1-d} - T &amp;gt; A_{j-1} - T &amp;gt; T - A_{j+k-1} &amp;gt; T - A_{j+k-1-d}\)&lt;/span&gt;. predicate holds: for all index &lt;span class="math"&gt;\(i &amp;lt;= j\)&lt;/span&gt;,
we have &lt;span class="math"&gt;\(|A_{i-1} - T| &amp;gt; |A_{i+k-1} - T|\)&lt;/span&gt;, which means we can discard first half of the array and move subrange to the right.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(A_j &amp;gt; A_{j+k} &amp;gt; T\)&lt;/span&gt;. In this case, we have &lt;span class="math"&gt;\(A_{j-1} - T &amp;gt; A_{j+k-1} - T\)&lt;/span&gt;, which imples that
&lt;span class="math"&gt;\(A_{j-1-d} - T &amp;gt; A_{j-1} - T &amp;gt; A_{j+k-1-d} - T &amp;gt; A_{j+k-1} - T\)&lt;/span&gt;. predicate holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once we verify the predicate satisifies the &lt;em&gt;main theorem&lt;/em&gt;, the only thing we left is to build the connection between the
invariant and predicate, and make sure the invariant holds during the loop execution. Let’s first list out the code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findClosestElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Notice that in the code we actually use &lt;span class="math"&gt;\(|A_{j+k} - T| \ge |A_j - T|\)&lt;/span&gt; instead of &lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt;. The reason
is because whenever there is a tie, the smaller elements are always preferred. Consider &lt;code&gt;[1,2,3,4,5]&lt;/code&gt; with &lt;span class="math"&gt;\(k = 4\)&lt;/span&gt; and &lt;span class="math"&gt;\(
T = 3\)&lt;/span&gt;. Then, both &lt;code&gt;[1,2,3,4]&lt;/code&gt; and &lt;code&gt;[2,3,4,5]&lt;/code&gt; are the closest &lt;span class="math"&gt;\(k\)&lt;/span&gt; elements to the &lt;span class="math"&gt;\(T\)&lt;/span&gt; and sum of the elements to &lt;span class="math"&gt;\(T\)&lt;/span&gt; distance
are the same, which is a tie. In this case, we prefer &lt;code&gt;[1,2,3,4]&lt;/code&gt;. If we strictly follow the predicate, we end up with
&lt;code&gt;[2,3,4,5]&lt;/code&gt;. Switching &lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt; to &lt;span class="math"&gt;\(|A_{j+k} - T| \ge |A_j - T|\)&lt;/span&gt; still maintains the invariant in the loop
because when &lt;span class="math"&gt;\(|A_{j+k} - T| = |A_j - T|\)&lt;/span&gt;, shifting the subrange to the right doesn’t give any improvement and by set &lt;code&gt;right&lt;/code&gt;
to mid, we still ensure that the optimal &lt;span class="math"&gt;\(j\)&lt;/span&gt; falls inside &lt;span class="math"&gt;\([\text{left}, \text{right}]\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;span class="math"&gt;\(|A_{j+k} - T| &amp;gt; |A_j - T|\)&lt;/span&gt; means we cannot move the subrange to the right to obtain the optimal subrange. We also show that
under the condition, we can discard the second half of the array. &lt;code&gt;mid&lt;/code&gt; represents &lt;span class="math"&gt;\(j\)&lt;/span&gt; in our condition and by not moving
subrange to right, we are saying that the optimal &lt;span class="math"&gt;\(j\)&lt;/span&gt; has to be the left of &lt;code&gt;mid&lt;/code&gt;. This implies that we can safely move
set &lt;span class="math"&gt;\(\text{right}\)&lt;/span&gt; to &lt;code&gt;mid&lt;/code&gt; and still maintains the invariant during the loop. On the other hand, &lt;span class="math"&gt;\(|A_{j-1} - T| &amp;gt; |A_{j+k-1} - T|\)&lt;/span&gt;
means that we cannot move the subrange to the left to obtain the optimal subrange. We also show that the inequality allows us
to discard the first half of the array. Since for given &lt;span class="math"&gt;\(j\)&lt;/span&gt; (&lt;code&gt;mid&lt;/code&gt;), we have &lt;span class="math"&gt;\(|A_{j-1} - T| &amp;gt; |A_{j+k-1} - T|\)&lt;/span&gt;. We cannot
move subrange (indicating by &lt;span class="math"&gt;\(j\)&lt;/span&gt; or &lt;code&gt;mid&lt;/code&gt;) to the left; we have to move to right. Thus, we set
&lt;span class="math"&gt;\(\text{left}\)&lt;/span&gt; to &lt;code&gt;mid+1&lt;/code&gt; to narrow down the search space while maintainng the invariant unchanged.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The above code is theoretically correct but it has fundamentally implementation issue: &lt;code&gt;mid&lt;/code&gt; can be 0,
which will lead to index out of bound error in &lt;code&gt;else if (fabs(x - arr[mid-1]) &amp;gt; fabs(x - arr[mid+k-1]))&lt;/code&gt;.
C++ doesn’t enforce index out of bound error (i.e., &lt;em&gt;undefined behavior&lt;/em&gt;) and the above code can run
successfully for certain complier on certain platform (leetcode obvious can). However, issue will happen
if you directly translate the above logic to another language. A safe way to do is to replace the &lt;code&gt;else if&lt;/code&gt;
statement with &lt;code&gt;else if ((mid &amp;gt;0 &amp;amp;&amp;amp; fabs(x - arr[mid-1]) &amp;gt; fabs(x - arr[mid+k-1])) || fabs(x - arr[mid]) &amp;gt; fabs(arr[mid+k] - x))&lt;/code&gt;,
which you can see is redundant and can be optimized. This is exactly what we are going to do next.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;One thing to note that &lt;code&gt;while(left &amp;lt; right)&lt;/code&gt; means we haven’t found the optimal &lt;span class="math"&gt;\(j\)&lt;/span&gt; yet, which implies that we have to
either move the subrange to left or move the subrange to right. This provides us the further opportunity to optimize the above
code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findClosestElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the first version, we check two conditions explicitly and do nothing if both conditions are not true. However,
as we state in the previous paragraph, since we are still in the &lt;code&gt;while&lt;/code&gt; loop, that means one of those two conditions will be true. 
In other words, there is no such case that both conditions are false and we are still in the loop. Thus, we can get rid of 
one of the conditions and use &lt;code&gt;else&lt;/code&gt; instead. Another way of thinking is that we do nothing if both conditions are failed
and thus this third do-nothing case can be combined with the second &lt;code&gt;else if (fabs(x - arr[mid-1]) &amp;gt; fabs(x - arr[mid+k-1]))&lt;/code&gt; condition to form a &lt;code&gt;else&lt;/code&gt; statement.&lt;/p&gt;
&lt;p&gt;There is another optimization code proposal I find online, which I don’t think it is correct:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;findClosestElements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But this code return the wrong answer for the following case: &lt;code&gt;arr = [5,4,3,2,1], x = 2, k = 4&lt;/code&gt;. The above
solution gives &lt;code&gt;[5,4,3,2]&lt;/code&gt;, which is wrong because &lt;code&gt;[4,3,2,1]&lt;/code&gt; is the closest elements to &lt;code&gt;2&lt;/code&gt;. To see this,
we can invoke the predicate: &lt;code&gt;5&lt;/code&gt; is 3 units away from &lt;code&gt;2&lt;/code&gt; but &lt;code&gt;1&lt;/code&gt; is only 1 unit away from &lt;code&gt;2&lt;/code&gt; (&lt;span class="math"&gt;\(|A_j - T| &amp;gt; |A_{j+k} - T|\)&lt;/span&gt;), 
which implies we can shift the subrange to the right. More straightforward way is to simply calculate the sum of distance of
each element: &lt;code&gt;[5,4,3,2]&lt;/code&gt; has sum &lt;code&gt;3+2+1 = 6&lt;/code&gt; while &lt;code&gt;[4,3,2,1]&lt;/code&gt; has sum &lt;code&gt;2+1+1 = 4&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;We give one example showing the essence of the binary search: main theorem, which is a formalization of how we discard values. 
Predicate helps us to find what to write in the &lt;code&gt;if&lt;/code&gt; statement and invariant helps us to make sure we find the correct value. 
In this post, we go through a relative formal proof of the correctness of our predicate. One thing to note that, the proof
is in fact induction: we use &lt;span class="math"&gt;\(d\)&lt;/span&gt; to show inequalities hold for any index &lt;span class="math"&gt;\(i &amp;gt; j\)&lt;/span&gt;. A nicer but equivalent way we can do is simply use
the induction and show &lt;span class="math"&gt;\(p(j+1)\)&lt;/span&gt; holds given &lt;span class="math"&gt;\(p(j)\)&lt;/span&gt; is correct (we actually do &lt;span class="math"&gt;\(p(j+d)\)&lt;/span&gt; holds given &lt;span class="math"&gt;\(p(j)\)&lt;/span&gt; is correct). Another point 
we should point out that we can derive the invariant
from predicate: we try to find the index of the first number that is among the k closest values for the given target &lt;span class="math"&gt;\(T\)&lt;/span&gt;. This is 
the exact same number that will &lt;strong&gt;first&lt;/strong&gt; give “yes” response to our predicate.&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/"&gt;TopCoder’s post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cs.stackexchange.com/questions/77364/searching-a-sorted-array-to-find-the-k-closest-values-to-a-target-value-t?rq=1"&gt;Stackexchange post: Searching a sorted array to find the k closest values to a target value T&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="algorithm"></category><category term="leetcode"></category><category term="cpp"></category></entry><entry><title>Trie</title><link href="https://zhu45.org/posts/2018/Jun/02/trie/" rel="alternate"></link><published>2018-06-02T22:30:00+08:00</published><updated>2018-06-02T22:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-06-02:/posts/2018/Jun/02/trie/</id><summary type="html">&lt;p&gt;A study of trie data structure&lt;/p&gt;</summary><content type="html">&lt;p&gt;Trie is a classic data structure (&lt;a href='#idreos2018data' id='ref-idreos2018data-1'&gt;Idreos et al., 2018&lt;/a&gt;) that is widely used in key-value store (&lt;a href='#zhang2018surf' id='ref-zhang2018surf-1'&gt;Zhang et al., 2018&lt;/a&gt;; &lt;a href='#wu2015lsm' id='ref-wu2015lsm-1'&gt;Wu et al., 2015&lt;/a&gt;). In this post, we describe the basics about the data structure.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#motivation"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#data-structure"&gt;Data Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation"&gt;Implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#applications"&gt;Applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;The main motivation for using trie is that we want to efficiently search for a word in a dataset of strings. We can use
hash table or balanced trees for this task. However, trie has its unique advantages:&lt;/p&gt;
&lt;p&gt;VS. Hash Table:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Hash table has &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; time complexity for looking up a key but it is not efficient for the operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finding all keys with a common prefix. We have to traverse all keys in hash table, which can be &lt;span class="math"&gt;\(O(n)\)&lt;/span&gt; (&lt;span class="math"&gt;\(n\)&lt;/span&gt; is 
the number of keys inserted). However, trie takes &lt;span class="math"&gt;\(O(k)\)&lt;/span&gt; (&lt;span class="math"&gt;\(k\)&lt;/span&gt; is the length of the prefix).&lt;/li&gt;
&lt;li&gt;Enumerating a dataset of strings in lexicographical order. There is a sorting on all strings (i.e. keys)
and thus &lt;span class="math"&gt;\(O(n\log n)\)&lt;/span&gt;. However, trie takes &lt;span class="math"&gt;\(O(n)\)&lt;/span&gt; time only.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search in hash table can be &lt;span class="math"&gt;\(O(n)\)&lt;/span&gt; if there are plenty of hash collisions. However, trie only takes &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt; (&lt;span class="math"&gt;\(m\)&lt;/span&gt; is 
the key length)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compared to hash table, trie saves space when storing many keys with the same prefix. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;VS. balanced trees:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search in balanced tree can take &lt;span class="math"&gt;\(O(m \log n)\)&lt;/span&gt; time. However, trie only takes &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="data-structure"&gt;Data Structure&lt;/h2&gt;
&lt;p&gt;To avoid unnecessary complexity, we assume we are working with a collection of strings which consist of only lower case alphabetics.&lt;/p&gt;
&lt;p&gt;&lt;img alt="trie" class="img-responsive" src="https://zhu45.org/images/trie.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A trie node contains two fields:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An array of &lt;span class="math"&gt;\(R\)&lt;/span&gt; links (&lt;code&gt;links&lt;/code&gt;), with each link representing one letter. A link connects two trie nodes together.
In our example, we have &lt;span class="math"&gt;\(R = 26\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;A boolean variable &lt;code&gt;isEnd&lt;/code&gt;, which indicates whether we reach the end of a string. This is needed because
if we are searching for a prefix, we should have &lt;code&gt;isEnd = false&lt;/code&gt;. On the other hand, if we reach the end of a string,
we have &lt;code&gt;isEnd = true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Please note that &lt;code&gt;isEnd = true&lt;/code&gt; doesn’t indicate that we are at leaf node of the trie. The boolean only indicates
whether we have reached the end of some string. In Figure 1, the end nodes of “wa” and “wax” are connected with each other.
If we require that there is no common prefix for the string (e.g. strings in the dataset don’t share the common prefix),
we then don’t need &lt;code&gt;isEnd&lt;/code&gt; boolean variable.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Insert a key into trie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We insert a key by searching into the trie. We start from the root and search a link, which corresponds to the first key character. There are two cases :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A link exists. Then we move down the tree following the link to the next child level. The algorithm continues with searching for the next key character.&lt;/li&gt;
&lt;li&gt;A link does not exist. Then we create a new node and link it with the parent’s link matching the current key character. We repeat this step until we encounter the last character of the key, then we mark the current node as an end node and the algorithm finishes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Time complexity: &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt; (In each iteration of the algorithm, we either examine or create a node in the trie till we reach the end of the key. This takes only &lt;span class="math"&gt;\(m\)&lt;/span&gt; operations.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Space complexity: &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt; (In the worst case newly inserted key doesn’t share a prefix with the the keys already inserted in the trie. We have to add &lt;span class="math"&gt;\(m\)&lt;/span&gt; new nodes, which takes us &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt; space.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for a key in a trie:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Each key is represented in the trie as a path from the root to the internal node or leaf. We start from the root with the first key character. We examine the current node for a link corresponding to the key character. There are two cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A link exist. We move to the next node in the path following this link, and proceed searching for the next key character.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A link does not exist. If there are no available key characters and current node is marked as &lt;code&gt;isEnd = true&lt;/code&gt; we return &lt;code&gt;true&lt;/code&gt;. Otherwise there are possible two cases in each of them we return &lt;code&gt;false&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are key characters left, but it is impossible to follow the key path in the trie, and the key is missing.&lt;/li&gt;
&lt;li&gt;No key characters left, but current node is not marked as &lt;code&gt;isEnd&lt;/code&gt;. Therefore the search key is only a prefix of another key in the trie.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Time complexity: &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt; (In each step of the algorithm we search for the next key character. In the worst case the algorithm performs &lt;span class="math"&gt;\(m\)&lt;/span&gt; operations.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Space complexity: &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for a key prefix in a trie:&lt;/p&gt;
&lt;p&gt;The approach is very similar to the one we used for searching a key in a trie. We traverse the trie from the root, till there are no characters left in key prefix or it is impossible to continue the path in the trie with the current key character. The only difference with the mentioned above search for a key algorithm is that when we come to an end of the key prefix, we always return true. We don’t need to consider the &lt;code&gt;isEnd&lt;/code&gt; mark of the current trie node, because we are searching for a prefix of a key, not for a whole key.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Time complexity: &lt;span class="math"&gt;\(O(m)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Space complexity: &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="implementation"&gt;Implementation&lt;/h2&gt;
&lt;p&gt;We implement the trie data structure in C++ &lt;a href="https://github.com/xxks-kkk/shuati/blob/master/leetcode/208-ImplementTrie/implementTrie.cc"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="applications"&gt;Applications&lt;/h2&gt;
&lt;p&gt;Trie is useful when we want to search some string based on the character appearance of the characters within the string:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Autocomplete"&gt;Autocomplete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Spell_checker"&gt;Spell checker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Longest_prefix_match"&gt;IP routing (Longest prefix matching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/T9_(predictive_text)"&gt;T9 predictive text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Solving &lt;a href="https://en.wikipedia.org/wiki/Boggle"&gt;Boggle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Huffman Codes (&lt;span class="math"&gt;\(\S\)&lt;/span&gt;10.1.2 in MAW(cpp))&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;We use a sequence of 1 and 0 to represent character in Huffman Codes. Thus, &lt;span class="math"&gt;\(R = 2\)&lt;/span&gt; (e.g. 1 and 0). However, 
to figure out the 0-1 encoding of each character, we cannot simply insert the character into trie. We should
use Huffman algorithm instead.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://leetcode.com/articles/implement-trie-prefix-tree/"&gt;Leetcode article on Trie&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%&amp;#64;#$&amp;#64;#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%&amp;#64;#$&amp;#64;#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;&lt;hr&gt;
&lt;p id='idreos2018data'&gt;Stratos Idreos, Kostas Zoumpatianos, Brian Hentschel, Michael&amp;nbsp;S Kester, and Demi Guo.
The data calculator: data structure design and cost synthesis from first principles and learned cost models.
In &lt;em&gt;Proceedings of the 2018 International Conference on Management of Data&lt;/em&gt;, 535–550. ACM, 2018. &lt;a class="cite-backref" href="#ref-idreos2018data-1" title="Jump back to reference 1"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;p id='wu2015lsm'&gt;Xingbo Wu, Yuehai Xu, Zili Shao, and Song Jiang.
Lsm-trie: an lsm-tree-based ultra-large key-value store for small data.
In &lt;em&gt;Proceedings of the 2015 USENIX Conference on Usenix Annual Technical Conference&lt;/em&gt;, 71–82. USENIX Association, 2015. &lt;a class="cite-backref" href="#ref-wu2015lsm-1" title="Jump back to reference 1"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;p id='zhang2018surf'&gt;Huanchen Zhang, Hyeontaek Lim, Viktor Leis, David&amp;nbsp;G Andersen, Michael Kaminsky, Kimberly Keeton, and Andrew Pavlo.
Surf: practical range query filtering with fast succinct tries.
In &lt;em&gt;Proceedings of the 2018 International Conference on Management of Data&lt;/em&gt;, 323–336. ACM, 2018. &lt;a class="cite-backref" href="#ref-zhang2018surf-1" title="Jump back to reference 1"&gt;↩&lt;/a&gt;&lt;/p&gt;
</content><category term="Data Struct &amp; Algo"></category><category term="trie"></category><category term="prefix tree"></category><category term="trees"></category><category term="data structures"></category></entry><entry><title>"Weighted Voting for Replicated Data"</title><link href="https://zhu45.org/posts/2018/May/15/weighted-voting-for-replicated-data/" rel="alternate"></link><published>2018-05-15T12:20:00+08:00</published><updated>2018-05-15T12:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-05-15:/posts/2018/May/15/weighted-voting-for-replicated-data/</id><summary type="html">&lt;p&gt;&amp;ldquo;Weighted Voting for Replicated Data&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-assumptions"&gt;Design Assumptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#algorithm"&gt;Algorithm&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#weighted-voting"&gt;Weighted Voting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quorum-based-reads-and-writes"&gt;Quorum-based Reads and Writes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#tuning-examples"&gt;Tuning &amp;amp; Examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#transactions-consistency"&gt;Transactions &amp;amp; Consistency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design an algorithm to maintain the replicated data: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Efficiently update the replicas&lt;/li&gt;
&lt;li&gt;Efficiently communicate with the replicas (i.e., read) to get the latest update&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="design-assumptions"&gt;Design Assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Each replicated object requires a version number&lt;/li&gt;
&lt;li&gt;No version number change during a transaction&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The paper is written for transaction. However, the quorum idea universally apply.
Thus, I omit some design assumptions related to transactions, which can be checked &lt;a href="http://www.cs.cornell.edu/Info/Courses/Spring-97/CS614/voting.html#2"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="algorithm"&gt;Algorithm&lt;/h2&gt;
&lt;h3 id="weighted-voting"&gt;Weighted Voting&lt;/h3&gt;
&lt;p&gt;Scene: a file is replicated across a set of replicas. We now need to read/write from this set of replicas to get/write the latest
copy of the file.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each replica (i.e., server, “Representative” in paper) gets &lt;strong&gt;M&lt;/strong&gt; votes&lt;/li&gt;
&lt;li&gt;Extra read-only copies get 0 votes (i.e., Weak Representatives)&lt;/li&gt;
&lt;li&gt;Each file is assigned &lt;strong&gt;K&lt;/strong&gt; votes&lt;/li&gt;
&lt;li&gt;We require R + W &amp;gt; K when handle each file&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;R&lt;/strong&gt;: the number of replicas we need to read before replying to the clients&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;W&lt;/strong&gt;: the number of replicas we need to write before replying to the clients&lt;/li&gt;
&lt;li&gt;We have at least one overlapping replica between R and W&lt;ul&gt;
&lt;li&gt;Guarantee at least one overlapping replica between R and W&lt;/li&gt;
&lt;li&gt;Guarantee every read will always see the latest write&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To read a file from a set of replicas, we gather R votes from the set of replicas&lt;ul&gt;
&lt;li&gt;Among R reads, we use the version number to detect which is the latest copy of the data and return to the client&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To write a file, we write to the set of replicas that with total votes equal to W (e.g., W=3, Replica 1 has 2 votes, Replica 2 has 0 votes, and Replica 3 has 1 votes; then
we need to write to Replica 1 and 3 to meet W requirement)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="quorum-based-reads-and-writes"&gt;Quorum-based Reads and Writes&lt;/h3&gt;
&lt;p&gt;Quorum-based system (e.g., &lt;a href="https://zhu45.org/posts/2018/Apr/14/dynamo-amazons-highly-available-key-value-store/"&gt;Dynamo&lt;/a&gt;) is one special case of Weighted Voting: M = 1; K = N (i.e., the number of replica in the system):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All reads go to R replicas&lt;/li&gt;
&lt;li&gt;All writes go to W replicas&lt;/li&gt;
&lt;li&gt;We require R + W &amp;gt; N&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="tuning-examples"&gt;Tuning &amp;amp; Examples&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;R = 1 &lt;span class="math"&gt;\(\rightarrow\)&lt;/span&gt; reads are efficient, writes are slow (every replica has to be updated)&lt;/li&gt;
&lt;li&gt;W = 1 &lt;span class="math"&gt;\(\rightarrow\)&lt;/span&gt; writes are efficient, reads are slow (every replica has to be read)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;p&gt;&lt;img alt="weighted voting examples" class="img-responsive" src="/images/weighted-voting-examples.png"/&gt;&lt;/p&gt;
&lt;p&gt;Let’s consider Example 1 in the figure above. Representative 1 gets 1 vote and the other two get 0 vote. Replica with 0 votes
are weak representatives, which are for read-only (i.e., local cached copy). We have R = 1, W = 1, K = 1 in this example. To read,
we have to read Representative 1 because we need 1 vote to satisfy R = 1. At the same time, to write, we need to write to 
Representative 1 for the same reason. In this example, Representative 1 can be the the server in the clients-server architecture
(e.g., NFS) and all the read/write have to go to the server. However, we can also set R = 0, which we can read from the
local cached copy directly (Representative 2 &amp;amp; 3 have 0 votes, which satisfy R requirement). But, in this case, weighted-voting
algorithm doesn’t guarantee that we can get the latest copy of the file.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Giving each replica (server) one vote: decentralized quorum system with high availability, low performance&lt;/li&gt;
&lt;li&gt;Giving one replica (server) all the votes: centralized system with high performance, low availability&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="transactions-consistency"&gt;Transactions &amp;amp; Consistency&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Each read or write is an atomic, isolated operation at each copy &lt;/li&gt;
&lt;li&gt;While the read is going on, there is no other writer at that copy (similarly for writes)&lt;/li&gt;
&lt;li&gt;Transactional isolation:&lt;ul&gt;
&lt;li&gt;lock all files the tx wants to read/write; Perform reads/writes; Unlock&lt;/li&gt;
&lt;li&gt;guarantees serializable transactions&lt;/li&gt;
&lt;li&gt;Obtaining the locks has to be done with a total order, otherwise deadlock is possible &lt;/li&gt;
&lt;li&gt;A tx can hold locks for a max time period&lt;ul&gt;
&lt;li&gt;to prevent certain transactions hold locks to long while others are waiting to obtain this lock&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;On total ordering, we have seen &lt;a href="https://zhu45.org/posts/2018/Mar/06/lamport-clocks-vector-clocks/"&gt;partial ordering in Lamport’s logical clock&lt;/a&gt;. However, partial ordering
allows the existence of concurrent events. To make partial ordering to &lt;a href="http://mathworld.wolfram.com/TotallyOrderedSet.html"&gt;total ordering&lt;/a&gt;, we need to add “comparability”, which means for any two
events, we can tell the ordering of the events (no cocurrent event allowed). Lamport uses the PID to solve this.
In weighted-voting, we enforce total ordering of locks to prevent deadlock. However, we don’t enforce total ordering
on transactions because operation in transactions can be interleaved and still guarantee the serializability (i.e.,
serial consistency). We could enforce total ordering on transactions but we cannot achieve the best performance in this case.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Three locks used: read lock, intention-to-write lock, commit lock&lt;ul&gt;
&lt;li&gt;Unlike write lock, intention-to-write lock allows the read lock because in serial consistency, 
all of a transaction’s writes appear to occur at transaction commit time. Thus, write lock is less ideal because
we don’t need write lock (which prevents read) at the very beginning of the transaction.&lt;/li&gt;
&lt;li&gt;Writes appear to occur when they are issued, but in fact are buffered until commit time by the stable file system.&lt;/li&gt;
&lt;li&gt;At commit time I-Write locks are converted to Commit locks, and the writing actually takes place.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Very interesting part of the paper on fine-grained locking management to improve concurrency of the system.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;p&gt;The paper doesn’t have a formal proof on R + W &amp;gt; K guarantees at least one overlapping replica between R and W. I think it would be
fun to fill this gap:&lt;/p&gt;
&lt;p&gt;Let’s suppose there are &lt;span class="math"&gt;\(N\)&lt;/span&gt; servers and for each server &lt;span class="math"&gt;\(i\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(k_i\)&lt;/span&gt; with &lt;span class="math"&gt;\(k_i &amp;gt; 0\)&lt;/span&gt; votes. Then&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
R  &amp;amp; = &amp;amp; \sum_{i=j}^m k_i \\
W  &amp;amp; = &amp;amp; \sum_{i=h}^t k_i \\
K  &amp;amp; = &amp;amp; \sum_{i=1}^N k_i
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;In words, we read server &lt;span class="math"&gt;\(j\)&lt;/span&gt; to &lt;span class="math"&gt;\(m\)&lt;/span&gt; to satisfy R votes requirement and we write
server &lt;span class="math"&gt;\(h\)&lt;/span&gt; to &lt;span class="math"&gt;\(t\)&lt;/span&gt; to satisfy W votes requirement. Note that &lt;span class="math"&gt;\(j\)&lt;/span&gt; to &lt;span class="math"&gt;\(m\)&lt;/span&gt;, for example,
doesn’t enforce that we have to pick servers in sequential order. We can always group
the servers we pick for R together and give them the sequential numbering.&lt;/p&gt;
&lt;p&gt;Now, let’s assume there is no overlapping replica between R and W. That means,
&lt;span class="math"&gt;\(\{j \dots m\} \cap \{h \dots t\} = \emptyset\)&lt;/span&gt;. Then we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray}
\sum_{i=j}^m k_i + \sum_{i=h}^t k_i &amp;amp; &amp;gt; &amp;amp; \sum_{i=1}^N k_i \\
\sum_{i=1}^N k_i - \sum_{i=h}^t k_i - \sum_{i=j}^m k_i &amp;amp; &amp;lt; &amp;amp; 0 \\
\sum_{i \in \{1 \dots h-1\} \cup \{t+1 \dots n\}} k_i - \sum_{i=j}^m k_i &amp;amp; &amp;lt; &amp;amp; 0   \label{1} \\
\sum_{i \in \{1 \dots h-1\} \cup \{t+1 \dots n\} \cup \{m+1 \dots n\}} k_i &amp;amp; &amp;lt; &amp;amp; 0 \label{2} \\
\end{eqnarray}
$$&lt;/div&gt;
&lt;p&gt;From equation &lt;span class="math"&gt;\(\eqref{1}\)&lt;/span&gt; to equation &lt;span class="math"&gt;\(\eqref{2}\)&lt;/span&gt;, since there is no intersection between two sets of servers, we can pick
either  &lt;span class="math"&gt;\(\{1 \dots h-1\}\)&lt;/span&gt; or &lt;span class="math"&gt;\(\{t+1 \dots n\}\)&lt;/span&gt; to contain &lt;span class="math"&gt;\(\{j \dots m\}\)&lt;/span&gt; (we happen to choose latter one). In other words,
any server in &lt;span class="math"&gt;\(\{j \dots m\}\)&lt;/span&gt; cannot in &lt;span class="math"&gt;\(\{h \dots t\}\)&lt;/span&gt; since there is no overlap based on our assumption. From the
last equation, we see that the sum of selected votes are smaller than 0, which is contracdiction. We always assign positive
votes to each server.&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dl.acm.org/citation.cfm?id=806583"&gt;Weighted Voting for Replicated Data paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pdfs.semanticscholar.org/presentation/337c/ddcf5753b3b06fd43044319ce51172ff89e4.pdf"&gt;Weighted Voting for Replicated Data slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.utexas.edu/~vijay/cs380D-s18/feb8-pnuts-voting.pdf"&gt;Vijay’s Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system, Data Struct &amp; Algo"></category><category term="papers"></category><category term="distributed systems"></category><category term="quorum"></category><category term="protocol"></category></entry><entry><title>"The Andrew File System (AFS)"</title><link href="https://zhu45.org/posts/2018/May/02/the-andrew-file-system-afs/" rel="alternate"></link><published>2018-05-02T23:30:00+08:00</published><updated>2018-05-02T23:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-05-02:/posts/2018/May/02/the-andrew-file-system-afs/</id><summary type="html">&lt;p&gt;&amp;ldquo;The Andrew File System (AFS)&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-assumptions"&gt;Design assumptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design"&gt;Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#nfs-vs-afs"&gt;NFS vs. AFS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design a distributed file system that can scale: a server can support as many clients as possible?&lt;/p&gt;
&lt;h2 id="design-assumptions"&gt;Design assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Most files were not frequently shared, and accessed sequentially in their entirety.&lt;/li&gt;
&lt;li&gt;System is used for casual usage (e.g., when a user logs into a different client, they expect some reasonable version of their files to show up there.)&lt;ul&gt;
&lt;li&gt;Not for concurrent access &amp;amp; updates scenario&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="design"&gt;Design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;whole-file caching:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;AFS is whole-file caching on the local disk of the client machine that is accessing a file&lt;/p&gt;
&lt;p&gt;&lt;code&gt;open()&lt;/code&gt; a file, the entire file (if it exists) is fetched from the server and stored in a file on your local disk. Subsequent application &lt;code&gt;read()&lt;/code&gt; and &lt;code&gt;write()&lt;/code&gt; operations are redirected to the local file system where the file is stored; thus, these operations require no network communication and are fast.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use client memory to cache blocks of file when access locally&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Contact the server (use TestAuth protocol) for future access of the file to see if client can use cache (i.e., no modification to the local cached file)&lt;ul&gt;
&lt;li&gt;Advantage: no network transfer of the file&lt;/li&gt;
&lt;li&gt;Disadvantge: too many contacts to server for cached file no-modification verification&lt;ul&gt;
&lt;li&gt;sol: use callback&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cache both directories and file contents&lt;ul&gt;
&lt;li&gt;motivation: server spends much CPU time traversing directories&lt;/li&gt;
&lt;li&gt;client caches and requests callback to directories along the way to the target file&lt;/li&gt;
&lt;li&gt;Sequential access assumption makes this technique works (e.g., access files within the same cached directory)&lt;/li&gt;
&lt;li&gt;Much effort spent on the client side (path traversing &amp;amp; cache) alleviates the load for server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Callback:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a way to reduce number of client/server interactions (mainly for TestAuth message verification)&lt;/li&gt;
&lt;li&gt;A callback is simply a promise from the server to the client that the server will inform the client when a file that the client is caching has been modified&lt;/li&gt;
&lt;li&gt;client assumes cached files are valid until the server tells it otherwise&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The idea of callback vs. TestAuth message is analogous to interrupt vs. polling&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cache consistency:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;consistency between processes on different machines:&lt;ul&gt;
&lt;li&gt;update visibility sol: flush-on-close&lt;/li&gt;
&lt;li&gt;cache staleness sol: server-initiated cache invalidation (“break” callback)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;consistency between processes on the same machine:&lt;ul&gt;
&lt;li&gt;update visibility sol: writes to a file are immediately visible to other local processes (i.e., a process does not have to wait until a file is closed to see its latest updates) (same as UNIX semantics: tail a log file and can see the writes
in real time)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Last writer wins (i.e., last closer wins) for concurrent modification of the same file&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The result is a file that was generated in its entirety either by one client or the other (unlike NFS, a file can contain
blocks from different clients)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Load balancing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;use volumes, which an administrator could move across servers to balance load&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Building the server with thread instead of process per client to reduce the overhead (e.g. context switching)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Crash Recovery:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clients:&lt;ul&gt;
&lt;li&gt;Client send out TestAuth message to validate its cache after recovery&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Servers:&lt;ul&gt;
&lt;li&gt;callbacks are kept in memory -&amp;gt; need to validate the cached file&lt;/li&gt;
&lt;li&gt;sol:&lt;ul&gt;
&lt;li&gt;having the server send a message to each client after recovery to let clients start to validate their cache&lt;/li&gt;
&lt;li&gt;clients send heartbeat message periodically to server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Even the cache is on disk, AFS can use client-side OS memory caching infrastructure to improve performance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AFS provides a true global namespace to clients, thus ensuring that all files were named the same way on all client machines.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;clients in NFS can mount NFS server anyway -&amp;gt; hard to administer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AFS has security and access-control lists&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nfs-vs-afs"&gt;NFS vs. AFS&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;For large-file (greater than memory) sequential re-read, AFS &amp;gt; NFS:&lt;ul&gt;
&lt;li&gt;AFS use local disk to cache entire file &lt;/li&gt;
&lt;li&gt;NFS can cache blocks in memory and have to refetch the file for re-read&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For access small subset of data within large files, NFS &amp;gt; AFS:&lt;ul&gt;
&lt;li&gt;AFS has to fetch entire file and send it back after modification&lt;/li&gt;
&lt;li&gt;NFS only read the blocks that need to be modified&lt;/li&gt;
&lt;li&gt;AFS is not good for append information to log periodically (little log writes that add small amounts of data to an existing large file)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;NFS&lt;/th&gt;
&lt;th&gt;AFS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cache unit&lt;/td&gt;
&lt;td&gt;block of a file&lt;/td&gt;
&lt;td&gt;whole file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache location&lt;/td&gt;
&lt;td&gt;memory&lt;/td&gt;
&lt;td&gt;local disk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache strategy&lt;/td&gt;
&lt;td&gt;cache block only&lt;/td&gt;
&lt;td&gt;cache directories and files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache invalidation&lt;/td&gt;
&lt;td&gt;polling (issue GETATTR)&lt;/td&gt;
&lt;td&gt;callback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrent update of the same file&lt;/td&gt;
&lt;td&gt;Blocks flushed to servers during update&lt;/td&gt;
&lt;td&gt;Last Writer Wins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Crash Recovery&lt;/td&gt;
&lt;td&gt;server crash is unnoticeable&lt;/td&gt;
&lt;td&gt;complex crash recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespace&lt;/td&gt;
&lt;td&gt;namespace is arbitrary across clients&lt;/td&gt;
&lt;td&gt;single namespace to all clients&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Several commonly-seen design techniques:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Force the clients to spend much more effort (cache directory and request callback) to reduce load on server&lt;ul&gt;
&lt;li&gt;techniques to avoid DDOS attack in security&lt;/li&gt;
&lt;li&gt;Mining in Bitcoin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cache consistency in file system is incapable of handling a file access from multiple clients (i.e., concurrent access)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need to implement explicit file-level locking on top of file system&lt;/li&gt;
&lt;li&gt;Need extra mechnaism to handle conflicts (e.g., concurrent updates):&lt;ul&gt;
&lt;li&gt;Google doc use git-like &lt;a href="https://www.quora.com/How-is-collaborative-document-editing-implemented-in-Google-Docs-How-are-infinite-undo-redo-implemented-separately-for-each-user-What-tasks-are-offloaded-to-the-client-and-which-are-done-at-the-server-itself"&gt;operational transformation&lt;/a&gt; to resolve conflict&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dropbox is inspired by AFS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The scalability in AFS is measured in terms of number of clients that a server can support. However, if we think about
scability in terms of the number of servers, NFS wins out due the stateless protocol and simple crash recovery&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/dist-afs.pdf"&gt;The Andrew File System (AFS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/M._Satyanarayanan"&gt;M. Satyanarayanan wikipedia page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category></entry><entry><title>"Petal: Distributed Virtual Disks"</title><link href="https://zhu45.org/posts/2018/May/02/petal-distributed-virtual-disks/" rel="alternate"></link><published>2018-05-02T02:20:00+08:00</published><updated>2018-05-02T02:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-05-02:/posts/2018/May/02/petal-distributed-virtual-disks/</id><summary type="html">&lt;p&gt;&amp;ldquo;Petal: Distributed Virtual Disks&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design a distributed storage system that is easy-to-use and easy-to-administer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Easy-to-use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simple Interface&lt;/li&gt;
&lt;li&gt;availability / fault tolerance&lt;/li&gt;
&lt;li&gt;transparency&lt;/li&gt;
&lt;li&gt;consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Easy-to-administer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;crash recovery (no manual needed)&lt;/li&gt;
&lt;li&gt;scability (scale up with the workloads without performance degration)&lt;/li&gt;
&lt;li&gt;add / remove nodes&lt;/li&gt;
&lt;li&gt;load balancing&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System design&lt;/h2&gt;
&lt;p&gt;&lt;img alt="petal client view" class="img-responsive" src="/images/petal-client-view.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Petal consists of a collection of network-connected servers that cooperatively manage a pool of physical disks&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Petal is different from distributed file system (NFS) in the sense that clients in NFS can directly access the server physical disks. However, Petal hides the physical resources through the layer of abstraction. The benefits of this abstraction:
- scale to a large size and reliable data storage over in long run
- support heterogeneous clients and client applications (e.g., different file systems) (Figure 2)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="petal physical view" class="img-responsive" src="/images/petal-physical-view.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="petal prototype" class="img-responsive" src="/images/petal-prototype.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clients (FS or DB) view Petal as a collection of &lt;em&gt;virtual disks&lt;/em&gt; (Figure 1)&lt;/li&gt;
&lt;li&gt;Disk-like Interface: data are read and written to Petal virtual disks in blocks (i.e., the basic tranfer unit) through RPC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="petal server modules" class="img-responsive" src="/images/petal-server-modules.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Software modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;liveness module:&lt;ul&gt;
&lt;li&gt;ensures that all servers in the system will agree on the operational status (running or crashed) of each other&lt;/li&gt;
&lt;li&gt;majority consensus (Paxos) + heatbeat&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;global state module:&lt;ul&gt;
&lt;li&gt;include information: current members of system + currently supported virtual disks&lt;/li&gt;
&lt;li&gt;consistently maintain information -&amp;gt; Paxos&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Virtual disk address -&amp;gt; physical disk address:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;virtual disk address form: &lt;virtual-disk-identifer, offset=""&gt;&lt;/virtual-disk-identifer,&gt;&lt;/li&gt;
&lt;li&gt;virtual disk identifier -&amp;gt; global map identifier (via. virtual disk directory)&lt;/li&gt;
&lt;li&gt;global map identifier decides the server for translating offset&lt;/li&gt;
&lt;li&gt;global map identifier &amp;amp; offset -&amp;gt; disk-identifier, disk-offset (via. phyiscal map on each server)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Separation of the translation data structures into global and local physical maps:
- keep bulk of mapping information local (minimizes the information kept globally, which is replicated and thus
hard to update)&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Global map:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One global map per virtual disk that specifies the tuple of servers spanned by the virtual disk&lt;/li&gt;
&lt;li&gt;immutable -&amp;gt; new global map if change virtual disk’s tuple of server / redundancy scheme&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Backup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;copy-on-write to create exact copy of a virtual disk at a specified point in time&lt;/li&gt;
&lt;li&gt;Use epoch-number as version number&lt;/li&gt;
&lt;li&gt;Create a snapshot consistent with client application level requires pauseing the application&lt;/li&gt;
&lt;li&gt;Can also use “crash-consistent” snapshot and later recovered by the application-specific recovery protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add server:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add to the membership of the Petal&lt;/li&gt;
&lt;li&gt;adjust liveness module to incorporate new server&lt;/li&gt;
&lt;li&gt;virtual disk reconfiguration (reconfigure existing virtual disks to use new resources -&amp;gt; data redistribution)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Virtual disk reconfiguration (data redistribution):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;data redistribution can take hours to finish (won’t compete network &amp;amp; disk traffic with write/read serving)&lt;/li&gt;
&lt;li&gt;Basic steps:&lt;ul&gt;
&lt;li&gt;create a new global map with redundancy scheme + server mapping&lt;/li&gt;
&lt;li&gt;change all virtual disk directory entries that refer to the old global map to refer to the new one&lt;/li&gt;
&lt;li&gt;redistribute data to servers according to new global map&lt;ul&gt;
&lt;li&gt;start with the most recent epoch that have not yet been moved (not return old data when READ)&lt;/li&gt;
&lt;li&gt;need to read/write during redistribution:&lt;ul&gt;
&lt;li&gt;READ: try the new global map first, then the old global map&lt;/li&gt;
&lt;li&gt;WRITE: use new global map&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Refinement:&lt;ul&gt;
&lt;li&gt;don’t need to change server mapping for an entire virtual disk before any data is moved (-&amp;gt; READ miss given new global map)&lt;/li&gt;
&lt;li&gt;sol:&lt;ul&gt;
&lt;li&gt;break virtual disk’s address into: old, new, fenced&lt;/li&gt;
&lt;li&gt;Requests to old/new use old/new global maps&lt;/li&gt;
&lt;li&gt;Use “Basic steps” for fenced only&lt;/li&gt;
&lt;li&gt;Once we have relocated everything in the fenced region, it becomes new region and we fence another part of the old region&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;tricks:&lt;ul&gt;
&lt;li&gt;keep the relative size of the fenced region small&lt;/li&gt;
&lt;li&gt;construct fenced region using small non-contiguous ranges distributed throughout the virtual disk (not single
contiguous region b/c fenced region may be heavily used)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="chained-declustering" class="img-responsive" src="/images/chained-declustering.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Data access and recovery:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use chained-declustered data access and recovery modules (chained-declustering):&lt;ul&gt;
&lt;li&gt;Two copies of each block of data are always stored on neighboring servers&lt;ul&gt;
&lt;li&gt;Server 1 fails, servers 0 and 2 will share server 1’s real load; server 3 will not have load increase&lt;/li&gt;
&lt;li&gt;Can offload load to a server to neighboring servers&lt;/li&gt;
&lt;li&gt;similar to consistent hashing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dynamic load balancing scheme:&lt;ul&gt;
&lt;li&gt;each client keep tracks of the number of requests it has pending at each server and always sends read requests to the
server with the short queue length&lt;/li&gt;
&lt;li&gt;Works for most of requests are from a few clients (not for many clients with occassional requests)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tolerate site failures:&lt;ul&gt;
&lt;li&gt;all the even-numbered servers at one site and all the odd-numbered servers at another site (less reliable
since data on a given server is replicate on neighboring only)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;one of two copies of each data block is denoted the primary. Rest are secondary.&lt;/li&gt;
&lt;li&gt;READ:&lt;ul&gt;
&lt;li&gt;Read from either primary or secondary&lt;/li&gt;
&lt;li&gt;Clients retry on failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;WRITE:&lt;ul&gt;
&lt;li&gt;Use primary always&lt;/li&gt;
&lt;li&gt;Mask the data as busy. Simultaneously sends write requests to its local copy and the secondary copy. When both requests complete, the busy bit is cleared and the client that issued the request is sent a status code indicating the success or failure of the operation.&lt;/li&gt;
&lt;li&gt;Optimization:&lt;ul&gt;
&lt;li&gt;write-ahead-logging with group commits (batch the busy bits update)&lt;/li&gt;
&lt;li&gt;cache the busy bits (avoid disk I/O to set busy bits)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Primary fail:&lt;ul&gt;
&lt;li&gt;the secondary marks the data element as stale on stable storage before writing it to its local disk. The server containing the primary copy will eventually have to bring all data elements marked stale up-to-date during its recovery process.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Petal’s limitation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High requirement to the network (use digital ATM Network)&lt;/li&gt;
&lt;li&gt;Petal’s use of the virtual disk abstraction adds an additional level of overhead, and can prevent application-specific disk optimizations that rely on careful placement of data.    &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pages.cs.wisc.edu/~remzi/Classes/739/Fall2017/Papers/petal96.pdf"&gt;Petal: Distributed Virtual Disks &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category><category term="storage"></category></entry><entry><title>"Sun's Network File System (NFS)"</title><link href="https://zhu45.org/posts/2018/May/01/suns-network-file-system-nfs/" rel="alternate"></link><published>2018-05-01T02:20:00+08:00</published><updated>2018-05-01T02:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-05-01:/posts/2018/May/01/suns-network-file-system-nfs/</id><summary type="html">&lt;p&gt;&amp;ldquo;Sun&amp;rsquo;s Network File System (NFS)&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System designs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design a distributed file system with transparent access to files from clients&lt;/p&gt;
&lt;h2 id="system-designs"&gt;System designs&lt;/h2&gt;
&lt;p&gt;&lt;img alt="nfs architecture" class="img-responsive" src="/images/nfs-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;the server stores the data on its disks, and clients request data through well-formed protocol messages&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Architecture advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;easy sharing of data across clients&lt;/li&gt;
&lt;li&gt;centralized administration (backup done on multiple servers instead of many clients)&lt;/li&gt;
&lt;li&gt;security (put server behind firewall)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transparency:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Location transparency: file name does not include name of the server where the file is stored&lt;/li&gt;
&lt;li&gt;Implemented using NFS Mount Protocol:&lt;ul&gt;
&lt;li&gt;Mount remote directories as local directories&lt;/li&gt;
&lt;li&gt;Maintain a Mount table with (directory, server) mapping&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="distributed file system architecture" class="img-responsive" src="/images/distributed-file-system-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Clients talk to server using RPC:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use RPC to forward every file system request; remote server executes each request as a local request; server
responds back with result (Example: &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/dist-nfs.pdf"&gt;OSTEP Figure 49.5&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Advantage: server provides a consistent view of the file system to clients&lt;/li&gt;
&lt;li&gt;Disadvantage: performance (use cache)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Crash Recovery:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;goal: simple and fast server crash recovery&lt;/li&gt;
&lt;li&gt;Use a stateless Protocol (NFSv2): the server doesn’t keep track of anything about what is happening at each client&lt;/li&gt;
&lt;li&gt;Stateful: server maintain a filedescriptor(an integer) to actual file relationship (unknown after recovery)&lt;/li&gt;
&lt;li&gt;Stateless: file handle (a unique identifier for each directory and file). &lt;ul&gt;
&lt;li&gt;Every client RPC call needs to pass a file handle&lt;/li&gt;
&lt;li&gt;Server returns file handle whenever needs (e.g., mkdir)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Server failure &amp;amp; Message loss:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client retries the request (READ, WRITE are idempotent in NFS)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Client side:&lt;ul&gt;
&lt;li&gt;cache file data and metadata by block that is read from server in local memory&lt;/li&gt;
&lt;li&gt;Cache serves as a temporary buffer for writes (allow asyncronous write)&lt;/li&gt;
&lt;li&gt;Advantage: reduce network usage, improve performance&lt;/li&gt;
&lt;li&gt;Disadvantage: write lost in memory after crash (safety vs. performance tradeoff)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Server side:&lt;ul&gt;
&lt;li&gt;server can buffer the write in memory and write to disk asychronously &lt;/li&gt;
&lt;li&gt;Problem: write in memory can lost&lt;/li&gt;
&lt;li&gt;Sol: &lt;ul&gt;
&lt;li&gt;battery-backed memory&lt;/li&gt;
&lt;li&gt;commit each WRITE to stable storage before ack WRITE success to clients&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cache consistency problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update visibility: when do updates from one client become visible at other clients?&lt;ul&gt;
&lt;li&gt;sol: flush-on-close (write-back cache):&lt;ul&gt;
&lt;li&gt;when a file is written to and subsequently closed by a client application, the client flushes all updates (i.e., dirty pages in the cache) to the server.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stale cache: once the server has a new version, how long before clients see the new version instead of an older cached copy?&lt;ul&gt;
&lt;li&gt;sol: issue GETATTR to get file stats (last modified date), if the time-of-modification is more recent than the time that the file was fetched into the client cache, the client invalidates the cache and subsequent reads will go to the server.&lt;/li&gt;
&lt;li&gt;Use attribute cache to reduce GETATTR requests (update attribute cache periodically)&lt;/li&gt;
&lt;li&gt;Still has problem: can still read stale value (polling interval, cache update/invalidation delayed by network)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;You may think the solution to cache consistency problems look a lot like &lt;a href="https://zhu45.org/posts/2018/Mar/07/cache-lease-consistency-invalidation/"&gt;write-back + invalidation&lt;/a&gt;. The geenral idea is the same. However, the solution here takes client’s perspective. However, the definitions in my previous
post takes server’s perspective. More formally, we call client’s perspective “client-initiated consistency protocol” and
server’s perspective “server-initiated consistency protocol”.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;NFS issues:&lt;ul&gt;
&lt;li&gt;multiple clients update the same file may get inconsistent view of the file (depends on cache update/invalidation, attribute
cache polling frequency)&lt;/li&gt;
&lt;li&gt;Clients crash may lose data in buffer (cache)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NFS Key features:&lt;ul&gt;
&lt;li&gt;Location-transparent naming&lt;/li&gt;
&lt;li&gt;Client-side and server-side caching for performance&lt;/li&gt;
&lt;li&gt;Stateless architecture&lt;/li&gt;
&lt;li&gt;Client-initiated consistency protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Good in NFS:&lt;ul&gt;
&lt;li&gt;Simple&lt;/li&gt;
&lt;li&gt;Highly portable (open protocol)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bad in NFS:&lt;ul&gt;
&lt;li&gt;Lack of strong consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/dist-nfs.pdf"&gt;Sun’s Network File System (NFS)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.utexas.edu/users/ans/classes/cs439/schedule.html"&gt;CS439 Alison’s slide “Other File Systems”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category></entry><entry><title>"MapReduce: Simplified Data Processing on Large Clusters"</title><link href="https://zhu45.org/posts/2018/Apr/30/mapreduce-simplified-data-processing-on-large-clusters/" rel="alternate"></link><published>2018-04-30T23:20:00+08:00</published><updated>2018-04-30T23:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-04-30:/posts/2018/Apr/30/mapreduce-simplified-data-processing-on-large-clusters/</id><summary type="html">&lt;p&gt;&amp;ldquo;MapReduce: Simplified Data Processing on Large Clusters&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem"&gt;Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-assumptions"&gt;Design assumptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#programming-model"&gt;Programming model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#execution"&gt;Execution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-design"&gt;System design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem"&gt;Problem&lt;/h2&gt;
&lt;p&gt;Design a simple-to-use (no exposure of messy details of parallelization, fault-tolerance, data distribution and load balancing to user)programming model (i.e., abstraction interface) that can process large amount of data 
in a reasonable amount of time.&lt;/p&gt;
&lt;h2 id="design-assumptions"&gt;Design assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Large clusters of commodity PCs connected together with switched Ethernet&lt;ul&gt;
&lt;li&gt;2-4GB memory Linux machine&lt;/li&gt;
&lt;li&gt;100 MB/s or 1 GB/s network bandwidth&lt;/li&gt;
&lt;li&gt;machine failures are common&lt;/li&gt;
&lt;li&gt;unreliable hardware&lt;/li&gt;
&lt;li&gt;distributed file system (use replication to provide availability and reliability)&lt;/li&gt;
&lt;li&gt;scheduler to schedule tasks to a set of available machines within a cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="programming-model"&gt;Programming model&lt;/h2&gt;
&lt;p&gt;The computation takes a set of input key/value pairs, and produces a set of output key/value pairs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Map&lt;/em&gt;, written by the user, takes an input pair and produces a set of &lt;em&gt;intermediate&lt;/em&gt; key/value pairs&lt;/li&gt;
&lt;li&gt;The MapReduce library groups together all intermediate values associated with the same intermediate key I and passes them to the &lt;em&gt;Reduce&lt;/em&gt; function.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;Reduce&lt;/em&gt; function, also written by the user, accepts an intermediate key I and a set of values for that key. It merges together these values to form a possibly smaller set of values.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;p&gt;Count of URL Access Frequency: The map function processes logs of web page requests and outputs ⟨URL, 1⟩. The reduce function adds together all values for the same URL and emits a ⟨URL, total count⟩ pair.&lt;/p&gt;
&lt;h2 id="execution"&gt;Execution&lt;/h2&gt;
&lt;p&gt;&lt;img alt="map reduce execution overview" class="img-responsive" src="/images/mapreduce-execution.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The Map invocations are distributed across multiple machines by automatically partitioning the input data
into a set of M splits.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reduce invocations are distributed by partitioning the intermediate key space into R pieces using a partitioning function
(e.g., &lt;span class="math"&gt;\(hash(key) \textbf{ mod } R\)&lt;/span&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execution Process:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The MapReduce library in the user program first splits the input files into M pieces. It then starts up many copies of the program on a cluster of machines.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One copy of the program is called &lt;em&gt;Master&lt;/em&gt;. The rest are workers that are assigned work by the master. The master picks idle workers and assigns each one a map task or a reduce task.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Worker assigned map task do Map job and buffer the output in memory&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Periodically, the buffered pairs are written to local disk, partitioned into R regions by the partitioning function. The locations of these buffered pairs on the local disk are passed back to the master, who is responsible for forwarding these locations to the reduce workers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reduce worker reads the buffered data from the local disks of the map workers using RPC. Perform Group by on the immediate keys.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Reduce worker do reduce job and append the output to a final output file of this reduce partition.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All Map and Reduce tasks are done, the master wakes up the user program and return the program control.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Map &amp;amp; Reduce tasks have three states: &lt;em&gt;idle&lt;/em&gt;, &lt;em&gt;in-progress&lt;/em&gt;, or &lt;em&gt;completed&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-design"&gt;System design&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the execution, the output are buffered in memory and write to disk in batch to reduce disk I/O overhead.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fault tolerance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Master pings every worker periodically to detect worker failure&lt;/li&gt;
&lt;li&gt;Completed map tasks are re-executed on a failure (intermediate output are stored in local disk and thus inaccessible)&lt;/li&gt;
&lt;li&gt;Completed reduce tasks are not re-executed on failures (results are in GFS, which are replicated already)&lt;/li&gt;
&lt;li&gt;Master Failure:&lt;ul&gt;
&lt;li&gt;Periodic checkpoints&lt;/li&gt;
&lt;li&gt;Aborts MapReduce computation if master fails (current implementation)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sequential consistency: when Map and Reduce operation is determinstic to the input file, the distributed execution output
is the same as the non-faulting sequential execution of the entire program:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Atomic commits of map and reduce task outputs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trade-off on each task size vs. M or R:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(O(M + R)\)&lt;/span&gt; scheduling descisions&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(O(M \dot R)\)&lt;/span&gt; states in memory&lt;/li&gt;
&lt;li&gt;small task size, large M or R given the input job size is fixed&lt;/li&gt;
&lt;li&gt;Large task size, small M or R given the input job size is fixed (make parallel meaningless)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Handle “straggler”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“Straggler”: a machine that takes an unusually long time to complete one of the last few map or reduce tasks in the computation.&lt;/li&gt;
&lt;li&gt;When a MapReduce operation is close to completion, the master schedules backup executions of the remaining &lt;em&gt;in-progress&lt;/em&gt; tasks. The task is marked as completed whenever either the primary or the backup execution completes. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Locality: schedule map tasks to the machines where the replicas of the input data is stored (input data can read locally
and consume no network bandwidth). This is saying of “push program to the data node”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Refinements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use a partition function on the intermediate keys such that, for example, all URLs from the same host to end up in the same
output file. For ease-to-use from the application layer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;within a given partition, the intermediate key/value pairs are processed in increasing key order. For efficient loopup in
the output file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optional &lt;em&gt;Combiner&lt;/em&gt; function that does partial merging of the intermediate keys on the map task worker before the data is sent over the network to the reduce worker (reduce network usage)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the MapReduce library detects which records cause deterministic crashes and skips these records in order to make forward progress.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Re-execution to provide fault tolearance is a commonly-seen technique (used in Spark as well) in “Big-data” paper&lt;/li&gt;
&lt;li&gt;Spawn multiple same tasks to handle “straggler” problem is also common&lt;/li&gt;
&lt;li&gt;Locality is a nice trick to use to reduce bandwidth usage&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/DJFKl_5JTnA?t=27m57s"&gt;Stonebraker’s video on database research&lt;/a&gt; mentions that MapReduce is no longer used
in Google. We as researcher should play critical on the papers produced by “whales” and not treat them as the golden standard
(we do because we lose connection to industry). Totally different topic.&lt;/li&gt;
&lt;li&gt;I don’t think MapReduce is a database work. I feel it just some framework that allows Google to get their job done
(If you think about Jeff Dean’s major focus is on programming languages not database). Unlike database, the framework is hard to generalize.&lt;/li&gt;
&lt;li&gt;Spot Remzi’s papers in the reference section. Neat!&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://static.googleusercontent.com/media/research.google.com/en//archive/mapreduce-osdi04.pdf"&gt;MapReduce: Simplified Data Processing on Large Clusters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category></entry><entry><title>"Scaling Distributed Machine Learning with the Parameter Server"</title><link href="https://zhu45.org/posts/2018/Apr/30/scaling-distributed-machine-learning-with-the-parameter-server/" rel="alternate"></link><published>2018-04-30T01:30:00+08:00</published><updated>2018-04-30T01:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-04-30:/posts/2018/Apr/30/scaling-distributed-machine-learning-with-the-parameter-server/</id><summary type="html">&lt;p&gt;&amp;ldquo;Scaling Distributed Machine Learning with the Parameter Server&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem-to-solve"&gt;Problem to solve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#challenges"&gt;Challenges&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-assumptions"&gt;Design assumptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design"&gt;Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem-to-solve"&gt;Problem to solve&lt;/h2&gt;
&lt;p&gt;Build a parameter server framework for distributed machine learning problems.&lt;/p&gt;
&lt;h2 id="challenges"&gt;Challenges&lt;/h2&gt;
&lt;p&gt;machine learning model has &lt;span class="math"&gt;\(10^9\)&lt;/span&gt; to &lt;span class="math"&gt;\(10^{12}\)&lt;/span&gt; shared parameters that need to frequently access&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;High network bandwidth requirement&lt;/li&gt;
&lt;li&gt;Synchronization cost and high machine latency can hurt model performance&lt;/li&gt;
&lt;li&gt;Fault tolerance is critical&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="design-assumptions"&gt;Design assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Machine learning algorithms are quite tolerant to perturbations&lt;/li&gt;
&lt;li&gt;Machine learning algorithms can be thought of consisting data + parameters&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="design"&gt;Design&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Parameter Server Architecture" class="img-responsive" src="/images/parameter-server-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use a group of parameter servers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can all serve one algorithm to have high availability&lt;/li&gt;
&lt;li&gt;can also run more than one algorithm simultaneously&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A server node in the server group maintains a partition of the globally shared parameters.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Partition might be a bad idea from fault tolearance and availability perspectives (the two main purposes
behind doing replication). By doing partition, we can reduce the workload on each server but we still effectively
use one server to serve a set of parameters, which makes the server group idea meaningless. In other words,
we want to use several servers to serve the same set of parameters to increase fault tolerance and availability.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Parameter servers in the server group partition keys using consistent hashing with virtual nodes (See &lt;a href="https://zhu45.org/posts/2018/Apr/14/dynamo-amazons-highly-available-key-value-store/"&gt;Dynamo Paper&lt;/a&gt; for details).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Virtual nodes adv: improve load balancing &amp;amp; recovery&lt;/li&gt;
&lt;li&gt;Consistent hashing adv: failure locality (only three nodes are affected)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Live replication of parameters between servers supports hot failover&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The communication of parameter updates and processing are batched to reduce network overhead (e.g. send a segment of a vector
or entire row of matrix)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The communication is also compressed to reduce network usage&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Parameters are stored using (key, value) vectors to facilitate linear algebra operations&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tasks are executed asynchronously: the caller can perform further computation immediately after issuing a task.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flexible consistency: training iterations vs. throughput tradeoff&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Eventual consistency: all tasks may be started simultaneously. Highest throughput (i.e., system efficiency) but
the algorithm may take more iterations to converge because the update may be on stale parameters. Thus, eventual consistency
model is recommended for algorithms that are agnostic to delayed parameter value.&lt;/li&gt;
&lt;li&gt;Sequential consistency: all tasks are executed one by one. Lowest throughput but all parameters are guaranteed to be latest.&lt;/li&gt;
&lt;li&gt;Bounded Delay: consistency model between sequential consistency and eventual consistency.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Server node are replicated after aggregation to reduce network usage&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Worker crash: we don’t recover the worker node because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;when training data is large, recover worker node is very expensive&lt;/li&gt;
&lt;li&gt;Losing a small amount of training data during optimization affects the model a little&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can spawn new task if one of machnies appear to be slow (to handle straggler problem)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Worker nodes may need to access the auxiliary metadata. In design, we always need to think of using metadata.&lt;/li&gt;
&lt;li&gt;A server manager node maintains a consistent view of the metadata of the servers, such as node liveness and the assignment of parameter partitions. This is the place to use Paxos.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Paxos can also be used when we have small set of parameter servers. Their membership can be stored using Paxos.
Usually, paxos cannot scale over 5 servers.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Machine learning algorithm tolerates stale data is the major point we exploit when design “Big data + ML” system&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cs.cmu.edu/~muli/file/parameter_server_osdi14.pdf"&gt;Scaling Distributed Machine Learning with the Parameter Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category></entry><entry><title>"Dynamo: Amazon’s Highly Available Key-value Store"</title><link href="https://zhu45.org/posts/2018/Apr/14/dynamo-amazons-highly-available-key-value-store/" rel="alternate"></link><published>2018-04-14T20:24:00+08:00</published><updated>2018-04-14T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-04-14:/posts/2018/Apr/14/dynamo-amazons-highly-available-key-value-store/</id><summary type="html">&lt;p&gt;&amp;ldquo;Dynamo: Amazon’s Highly Available Key-value Store&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem-motivation"&gt;Problem, Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-assumptions-and-requirements"&gt;System Assumptions and Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-considerations"&gt;Design Considerations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#design-requirement"&gt;Design Requirement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#architecture"&gt;Architecture&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#partitioning-algorithm"&gt;Partitioning Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#replication"&gt;Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#data-versioning"&gt;Data Versioning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#execution-of-get-and-put-operations"&gt;Execution of get () and put () operations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#handling-temporary-failures-hinted-handoff"&gt;Handling temporary failures: Hinted Handoff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#handling-permanent-failures-replica-synchronization"&gt;Handling permanent failures: Replica synchronization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#membership-and-failure-detection"&gt;Membership and Failure Detection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks-thoughts"&gt;Remarks &amp;amp; Thoughts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-readings"&gt;Further Readings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem-motivation"&gt;Problem, Motivation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;How to build a highly available (i.e. reliability) and scalable distributed key-value storage system?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-assumptions-and-requirements"&gt;System Assumptions and Requirements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Query Model: simple KV store operations: read &amp;amp; write&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;store small objects (&amp;lt;= 1 MB)&lt;/li&gt;
&lt;li&gt;no operations span multiple data items; no need for relational schema&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ACID properties: trade consistency in ACID for high availability&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;no isolation guarantees&lt;/li&gt;
&lt;li&gt;permits only single key updates&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Efficiency: commodity machines; stringent latency requirements specified by SLAs&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SLA (Sevice Level Agreement): a contract where a client and a service agree on several system-related characteristics: client’s expected request rate distribution for a particular API, the expected service latency under those conditions, etc.&lt;/li&gt;
&lt;li&gt;Dynamo:&lt;ul&gt;
&lt;li&gt;SLAs measured at the 99.9th percentile of the distribution (e.g., a response within 300ms for 99.9% of its requests for a peak client load of 500 requests per second)&lt;/li&gt;
&lt;li&gt;configurable: to meet service latency &amp;amp; throughput requirements&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dynamo is an AP system&lt;/li&gt;
&lt;li&gt;Measuring tail latency instead of average latency is because Dynamo wants to optimize the worst case scenario. In the system
is designed for the common usage situations, average latency is a fine measurement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="design-considerations"&gt;Design Considerations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Strong consistency and high data availability cannot be achieved simultaneously&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dynamo sacrifice strong consistency: Dynamo is designed to be an eventually consistent data store; that is all updates reach all replicas eventually.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Increase availability for system prone to server and network failures: Optimistic replication techniques&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;changes are allowed to propagate to replicas in the background, and concurrent, disconnected work is tolerated.&lt;/li&gt;
&lt;li&gt;Conflicts must be detected and reolved:&lt;ul&gt;
&lt;li&gt;When (whether conflicts should be resolved during reads or writes?):&lt;ul&gt;
&lt;li&gt;Dynamo: resolved when read; writes are never rejected &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Who (who performs the process of conflict resolution: data store or application?):&lt;ul&gt;
&lt;li&gt;Dynamo: the application; data store implements a simple policy (i.e., “last write wins”)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Incremental scalability: scale out one storage host (&lt;em&gt;node&lt;/em&gt;) at a time with minimal impact&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Symmetry: every node in Dynamo should have the same set of responsibilities as its peers (i.e., no special nodes)&lt;/li&gt;
&lt;li&gt;Decentralization: design favors decentralized peer-to-peer techniques&lt;/li&gt;
&lt;li&gt;Heterogeneity: system needs to be able to exploit heterogeneity in the infrastructure it runs on (e.g. the work distribution must be proportional to the capabilities of the individual servers)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="design-requirement"&gt;Design Requirement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;“Always writeable”: no updates are rejected due to failures or concurrent writes&lt;/li&gt;
&lt;li&gt;All nodes are assumed to be trusted&lt;/li&gt;
&lt;li&gt;No support for hierarchical namespaces (a norm in many file systems) or complex relational schema&lt;/li&gt;
&lt;li&gt;Built for latency sensitvie applications: at least 99.9% of read and write operations to be performed within a few hundred milliseconds&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The architecture of a storage system in a production setting needs to include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;actual data persistence component&lt;/li&gt;
&lt;li&gt;load balancing&lt;/li&gt;
&lt;li&gt;membership and failure detection&lt;/li&gt;
&lt;li&gt;failure recovery&lt;/li&gt;
&lt;li&gt;replica synchronization&lt;/li&gt;
&lt;li&gt;overload handling&lt;/li&gt;
&lt;li&gt;state transfer&lt;/li&gt;
&lt;li&gt;concurrency and job scheduling&lt;/li&gt;
&lt;li&gt;request marshalling&lt;/li&gt;
&lt;li&gt;request routing&lt;/li&gt;
&lt;li&gt;system monitoring and alarming&lt;/li&gt;
&lt;li&gt;configuration management&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="Dynamo Architecture Main Techniques" class="img-responsive" src="/images/dynamo-arch-overview.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The relation between Table 1 entry and the following sections:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Partitioning (Partitioning Algorithm, Replication)&lt;/li&gt;
&lt;li&gt;High Availability for writes (Data Versioning)&lt;/li&gt;
&lt;li&gt;Handling temporary failures (Execution of get () and put () operations, Handling temporary failures: Hinted Handoff)&lt;/li&gt;
&lt;li&gt;Recovering from permanent failures (Handling permanent failures: Replica synchronization)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3 id="partitioning-algorithm"&gt;Partitioning Algorithm&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dynamo’s partitioning scheme relies on consistent hashing to distribute the load across multiple storage hosts (i.e., nodes).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consistent hashing:&lt;/p&gt;
&lt;p&gt;the output range of a hash function is treated as a fixed circular space or “ring” (i.e. the largest hash value wraps around to the smallest hash value). Each node in the system is assigned a random value within this space which represents its “position” on the ring. Each data item identified by a key is assigned to a node by hashing the data item’s key to yield its position on the ring, and then walking the ring clockwise to find the first node with a position larger than the item’s position. Thus, each node becomes responsible for the region in the ring between it and its predecessor node on the ring.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pro &amp;amp; Cons of consistent hashing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pro:&lt;ul&gt;
&lt;li&gt;departure or arrival of a node only affects its immediate neighbors and other nodes remain unaffected&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cons:&lt;ul&gt;
&lt;li&gt;the random position assignment of each node on the ring leads to non-uniform data and load distribution&lt;/li&gt;
&lt;li&gt;The basic algorithm is oblivious to the heterogeneity in the performance of nodes 
(i.e., some node may have a more powerful setup but consistent hashing treat it the same as others)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dynamo uses a variant of consistent hashing:&lt;/p&gt;
&lt;p&gt;Instead of mapping a node to a single point in the circle, each node gets assigned to multiple points in the ring. To this end, Dynamo uses the concept of “&lt;em&gt;virtual nodes&lt;/em&gt;”. A virtual node looks like a single node in the system, but each node can be responsible for more than one virtual node. Effectively, when a new node is added to the system, it is assigned multiple positions (i.e., “&lt;em&gt;tokens&lt;/em&gt;”) in the ring.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Advantages of using virtual nodes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If a node becomes unavailable (due to failures or routine maintenance), the load handled by this node is evenly dispersed across the remaining available nodes&lt;/li&gt;
&lt;li&gt;When a node becomes available again, or a new node is added to the system, the newly available node accepts a roughly equivalent amount of load from each of the other available nodes&lt;/li&gt;
&lt;li&gt;The number of virtual nodes that a node is responsible can decided based on its capacity, accounting for heterogeneity in the physical infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="replication"&gt;Replication&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To achieve high availability and durability, Dynamo replicates its data on multiple hosts.&lt;/p&gt;
&lt;p&gt;Each data item is replicated at N hosts, where N is a parameter configured “per-instance”. Each key, k, is assigned to a coordinator node (the node that a key is assigned to in consistent hashing; the first among the top N nodes in the preference list). The coordinator is in charge of the replication of the data items that fall within its range. In addition to locally storing each key within its range, the coordinator replicates these keys at the N-1 clockwise successor nodes in the ring. This results in a system where each node is responsible for the region of the ring between it and its Nth predecessor.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Dynamo Replication Example" class="img-responsive" src="/images/dynamo-replication-example.png"/&gt;&lt;/p&gt;
&lt;p&gt;Example: node B replicates the key k at nodes C and D in addition to storing it locally. Node D will store the keys that fall in the ranges (A, B], (B, C], and (C, D].&lt;/p&gt;
&lt;p&gt;The list of nodes that is responsible for storing a particular key is called the &lt;em&gt;preference list&lt;/em&gt;. Every node in the system can determine which nodes should be in this list for any particular key. To account for node failures, preference list contains more than N nodes. The preference list for a key is constructed by skipping positions in the ring to ensure that the list contains only distinct physical nodes (first N virtual nodes may all be hosted by one physical node).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="data-versioning"&gt;Data Versioning&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dynamo provides eventual consistency, which allows for updates to be propagated to all replicas asynchronously.&lt;/li&gt;
&lt;li&gt;Dynamo allows multiple versions of the same object but if reconcilation fails, the client must perform the reconciliation in order to collapse multiple branches of data evolution back into one (semantic reconciliation).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Works like Git: if Git can merge different modifications into one, Git is done automatically for you. If not, you (client)
have to manually reconcile conflicts.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Dynamo uses &lt;a href="https://zhu45.org/posts/2018/Mar/06/lamport-clocks-vector-clocks/"&gt;vector clocks&lt;/a&gt; in order to capture causality between different versions of the same object. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Dynamo Data Versioning Example" class="img-responsive" src="/images/dynamo-data-version.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Each object (e.g., D5) contains a vector clock (e.g., &lt;code&gt;([Sx,3],[Sy,1],[Sz,1])&lt;/code&gt;). Note that it is not a list of vector clocks.
You can think about &lt;code&gt;Sx&lt;/code&gt;, &lt;code&gt;Sy&lt;/code&gt;, &lt;code&gt;Sz&lt;/code&gt; as process names to map to the original vector clock example.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Dynamo uses a clock truncation scheme to control the size of vector clocks&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="execution-of-get-and-put-operations"&gt;Execution of get () and put () operations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Any storage node in Dynamo is eligible to receive client get and put operations for any key&lt;/li&gt;
&lt;li&gt;Read and write operations involve the first N &lt;em&gt;healthy&lt;/em&gt; nodes in the preference list, skipping over those that are down or inaccessible (remember preference list contains more than N nodes).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To maintain consistency among its replicas, Dynamo uses a consistency protocol similar to those used in quorum systems.&lt;/p&gt;
&lt;p&gt;This protocol has two key configurable values: R and W. R is the minimum number of nodes that must participate in a successful read operation. W is the minimum number of nodes that must participate in a successful write operation. Setting R and W such that R + W &amp;gt; N yields a quorum-like system. In this model, the latency of a get (or put) operation is dictated by the slowest of the R (or W) replicas. For this reason, R and W are usually configured to be less than N, to provide better latency.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Dynamo client applications can tune the values of N, R and W to achieve their desired levels of performance, availability and durability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;N determines the durability of each object&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The values of W and R impact object availability, durability and consistency&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If W is set to 1, then the system will never reject a write request as long as there is at least one node in the system that can successfully process a write request&lt;/li&gt;
&lt;li&gt;low values of W and R can increase the risk of inconsistency as write requests are deemed successful and returned to the clients even if they are not processed by a majority of the replicas; This also introduces a vulnerability window for durability when a write request is successfully returned to the client even though it has been persisted at only a small number of nodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Execution of put() operation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Coordinator generates the vector clock for the new version&lt;/li&gt;
&lt;li&gt;Coordinator writes the new version locally&lt;/li&gt;
&lt;li&gt;Coordinator sends the new version + vector clock to the N highest-ranked reachable nodes&lt;/li&gt;
&lt;li&gt;If at least W-1 nodes respond then the write is considered successful.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- !!!note
    From the execution of put() operation, we can tell Dynamo guarantees atomicity for put() operation. Atomicity in this context
    means that once the application receives the success signal from put() operation, he can assume that the data written by put()
    has been stored in Dynamo successfully. There is no way that put() operation success but the data being written is actually lost.
    [ref](https://cs.stackexchange.com/questions/45809/what-does-atomicity-mean-in-distributed-systems) --&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Execution of get() operation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Coordinator requests all existing versions of data for that key from the N highest-ranked reachable nodes in the preference list for that key&lt;/li&gt;
&lt;li&gt;Coordinator waits for R responses before returning the result to the client&lt;/li&gt;
&lt;li&gt;Reconcilation done by the applications is written back&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="handling-temporary-failures-hinted-handoff"&gt;Handling temporary failures: Hinted Handoff&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cons of traditional quorum approach:&lt;/p&gt;
&lt;p&gt;Unavailable during server failures and network partitions and durability reduced under the simplest of failure conditions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Doesn’t strict quorum membership and use “sloppy quorum”:&lt;/p&gt;
&lt;p&gt;all read and write operations are performed on the first N &lt;em&gt;healthy&lt;/em&gt; nodes from the preference list, which may not always be the first N nodes encountered while walking the consistent hashing ring.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hinted Handoff:&lt;/p&gt;
&lt;p&gt;Consider the example of Dynamo configuration given in Figure 2 with N=3. In this example, if node A is temporarily down or unreachable during a write operation then a replica that would normally have lived on A will now be sent to node D. This is done to maintain the desired availability and durability guarantees. The replica sent to D will have a hint in its metadata that suggests which node was the intended recipient of the replica (in this case A). Nodes that receive hinted replicas will keep them in a separate local database that is scanned periodically. Upon detecting that A has recovered, D will attempt to deliver the replica to A. Once the transfer succeeds, D may delete the object from its local store without decreasing the total number of replicas in the system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using hinted handoff, Dynamo ensures that the read and write operations are not failed due to temporary node or network failures.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="handling-permanent-failures-replica-synchronization"&gt;Handling permanent failures: Replica synchronization&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dynamo implements an anti-entropy (replica synchronization) protocol to keep the replicas synchronized.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To detect the inconsistencies between replicas faster and to minimize the amount of transferred data, Dynamo uses Merkle trees:&lt;/p&gt;
&lt;p&gt;A Merkle tree is a hash tree where leaves are hashes of the values of individual keys. Parent nodes higher in the tree are hashes of their respective children. The principal advantage of Merkle tree is that each branch of the tree can be checked independently without requiring nodes to download the entire tree or the entire data set. Moreover, Merkle trees help in reducing the amount of data that needs to be transferred while checking for inconsistencies among replicas. For instance, if the hash values of the root of two trees are equal, then the values of the leaf nodes in the tree are equal and the nodes require no synchronization. If not, it implies that the values of some replicas are different. In such cases, the nodes may exchange the hash values of children and the process continues until it reaches the leaves of the trees, at which point the hosts can identify the keys that are “out of sync”. Merkle trees minimize the amount of data that needs to be transferred for synchronization and reduce the number of disk reads performed during the anti-entropy process.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="membership-and-failure-detection"&gt;Membership and Failure Detection&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use explicit command to add and remove nodes from a Dynamo Ring:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adv: nodes may be temporarily down and we don’t have to immediately redistribute workload (i.e., think they are out of ring membership) whenever some node are uncontactable. Redistribute workload is expensive.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To prevent logical partitions, some Dynamo nodes play the role of seeds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Case: node A joins the ring; node B joins the ring; but A and B would consider each other be the member of the ring at once&lt;/li&gt;
&lt;li&gt;Seeds are nodes that are discovered via an external mechanism and are known to all nodes.&lt;/li&gt;
&lt;li&gt;Typically seeds are fully functional nodes in the Dynamo ring.&lt;/li&gt;
&lt;li&gt;Because all nodes eventually reconcile their membership with a seed, logical partitions are highly unlikely.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;node A may consider node B failed if node B does not respond to node A’s messages (even if B is responsive to node C’s messages)&lt;/p&gt;
&lt;p&gt;Decentralized failure detection protocols use a simple gossip-style protocol that enable each node in the system to learn about the arrival (or departure) of other nodes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks-thoughts"&gt;Remarks &amp;amp; Thoughts&lt;/h2&gt;
&lt;p&gt;I really like this paper. It connects all the classic distributed techniques (i.e., gossip, quorum, consistent hashing, merkle tree)
into one.&lt;/p&gt;
&lt;h2 id="further-readings"&gt;Further Readings&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Some views from peers &lt;a href="http://pages.cs.wisc.edu/~swift/classes/cs739-fa14/blog/2014/09/post.html#comments"&gt;CS 739 Reviews - Fall 2014&lt;/a&gt;, &lt;a href="http://pages.cs.wisc.edu/~swift/classes/cs739-sp12/blog/2012/01/post.html"&gt;CS 739 Reviews - Spring 2012&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf"&gt;Dynamo: Amazon’s Highly Available Key-value Store&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.puncsky.com/blog/2013/04/06/dynamo-kv-store"&gt;Tian Pan’s Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.shangzeyuan.com/static/talks/dynamo.pdf"&gt;Zeyuan’s Talk on Dynamo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category><category term="storage"></category><category term="consistent hashing"></category><category term="quorum"></category><category term="merkle tree"></category></entry><entry><title>"Fast Crash Recovery in RAMCloud"</title><link href="https://zhu45.org/posts/2018/Apr/09/fast-crash-recovery-in-ramcloud/" rel="alternate"></link><published>2018-04-09T22:00:00+08:00</published><updated>2018-04-09T22:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-04-09:/posts/2018/Apr/09/fast-crash-recovery-in-ramcloud/</id><summary type="html">&lt;p&gt;&amp;ldquo;Fast Crash Recovery in RAMCloud&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem-motivation"&gt;Problem, Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#challenges"&gt;Challenges&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#assumptions"&gt;Assumptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#architecture"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#durability-and-availability"&gt;Durability and Availability&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#buffered-logging"&gt;Buffered Logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fast-recovery"&gt;Fast Recovery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#other-interesting-details"&gt;Other interesting details&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks-thoughts"&gt;Remarks &amp;amp; Thoughts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="problem-motivation"&gt;Problem, Motivation&lt;/h2&gt;
&lt;p&gt;RAMCloud is a large-scale general-purpose DRAM storage system for datacenters. 
The system is motivated by the fact that Large-scale apps struggle with utilizing
DRAM to its full potential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DRAM is still majorly used as a cache for some other storage system&lt;/li&gt;
&lt;li&gt;Developers have to manage consistency between caches in DRAM and its storage system&lt;/li&gt;
&lt;li&gt;Cache misses and backing store overheads&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="RAMCloud concept" class="img-responsive" src="/images/RAMCloud-datacenter.png" style="height 300px"/&gt;&lt;/p&gt;
&lt;p&gt;It has four design goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scalbility: 1000-10000 commodity servers with 32-64 GB DRAM/server&lt;/li&gt;
&lt;li&gt;Low latency: uniform low-latency access (5-10 μs round-trip times for small read operations)&lt;/li&gt;
&lt;li&gt;High throughput: 1M ops/sec/server&lt;/li&gt;
&lt;li&gt;High durability and availability&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This paper focuses on the “high durability and availability”. Replicating all data (x3) in DRAM fix
some availability issue but triple the cost and energy usage of the system. Thus, RAMCloud only 
stores a single copy of data in DRAM, which brings the problem of availability: what happens when server
crashes? RAMCloud’s solution to the availability problem is fast crash recovery. Then the problem 
becomes how to recover from crash within 1s~2s for 64GB or more DRAM data?&lt;/p&gt;
&lt;h2 id="challenges"&gt;Challenges&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Durability: RAM is lack of durability. Data is unavailable on crashed nodes.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Availability: How to recover as soon as possible?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast writes: Synchronous disk I/O’s during writes?? Too slow &lt;/li&gt;
&lt;li&gt;Fast crash recovery: Data unavailable after crashes?? No!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Large scale: 10,000 nodes, 100TB to 1PB&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="assumptions"&gt;Assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use low-latency Infiniband NICs and switches &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ethernet switches and NICs typically add at least 200-500 μs to round-trip latency in a large datacenter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DRAM uses an auxiliary power source&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;to ensure that buffers can be written to stable storage after a power failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Every byte of data is in DRAM&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;
&lt;p&gt;&lt;img alt="RAMCloud main architecture" class="img-responsive" src="/images/RAMCloud-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Each storage server contains a master and a backup. A central coordinator &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; manages the server pool and &lt;a href="https://zhu45.org/posts/2018/Mar/08/pnuts-yahoos-hosted-data-serving-platform/"&gt;tablet&lt;/a&gt; configuration. Client applications run on separate machines and access RAMCloud using a client library that makes remote procedure calls.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;master: manages RAMCloud objects in its DRAM and services client requests&lt;/li&gt;
&lt;li&gt;backup: stores redundant copies of objects from other masters using its disk or flash memory&lt;/li&gt;
&lt;li&gt;coordinator: manages configuration information such as the network addresses of the storage servers and the locations of objects&lt;/li&gt;
&lt;li&gt;tablets: consecutive key ranges within a single table&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data model: object consists of [identifier(64b), version(64b), Blob(&amp;lt;=1MB)]&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="durability-and-availability"&gt;Durability and Availability&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Durability: 1 copy in DRAM; Backup copies on disk/flash: durability ~ free!&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Availiability: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast writes: Buffered Logging&lt;/li&gt;
&lt;li&gt;Fast crash recovery: Large-scale parallelism to reconstruct data (similar to MapReduce)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="buffered-logging"&gt;Buffered Logging&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Buffered Logging" class="img-responsive" src="/images/buffered-logging.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;When a master receives a write requests, it updates its in-memory log and forwards the new data to several backups, which buffer the data in their memory. Master maintains a hash table to record locations of data objects. The data is eventually written to disk or flash in large batches. Backups must use an auxiliary power source to ensure that buffers can be written to stable storage after a power failure.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No disk I/O during write requests&lt;/li&gt;
&lt;li&gt;Master’s memory also log-structured&lt;/li&gt;
&lt;li&gt;Log cleaning ~ generational garbage collection&lt;/li&gt;
&lt;li&gt;master’s log is divided into 8MB segments&lt;/li&gt;
&lt;li&gt;Hash table is used for quickly lookup object in log&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This part idea borrows from &lt;a href="http://pages.cs.wisc.edu/~remzi/OSTEP/file-lfs.pdf"&gt;log-structured file system&lt;/a&gt;. Log structure
in memory is thought to be interesting by Vijay.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="fast-recovery"&gt;Fast Recovery&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Fast Recovery Overview" class="img-responsive" src="/images/fast-recovery-overview.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Three different recovery schemas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One recovery master, small backup servers (disk bandwidth bottleneck)&lt;/li&gt;
&lt;li&gt;One recovery master, large backup servers (network bandwidth bottleneck)&lt;/li&gt;
&lt;li&gt;Several recovery masters, large backup servers (good!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Recovery Overview" class="img-responsive" src="/images/recovery.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Divide each master’s data into partitions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Partition and scatter log data to more backups randomly. So backup data can be read in parallel when the master crashed.&lt;/li&gt;
&lt;li&gt;Recover each partition on a separate recovery master&lt;/li&gt;
&lt;li&gt;Partitions based on tables &amp;amp; key ranges, not log segment&lt;/li&gt;
&lt;li&gt;Each backup divides its log data among recovery masters&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each mater computes the strategy to form partitions and upload the strategy to coordinator as &lt;em&gt;will&lt;/em&gt;. Coordinator follows crashed master’s will to 
divide crashed master’s data into partitions and assign the recoverying work to recovery masters (see section 3.5.3)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="log distribution" class="img-responsive" src="/images/log-distribution.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="recovery ops" class="img-responsive" src="/images/recovery-ops.png"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="recovery ops details" class="img-responsive" src="/images/recovery-ops-details.png"/&gt;&lt;/p&gt;
&lt;h2 id="other-interesting-details"&gt;Other interesting details&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Each RAMCloud master decides independently where to place each replica, using a combination of randomization and refinement.&lt;/p&gt;
&lt;p&gt;When a master needs to select a backup for a segment, it chooses several candidates at random from a list of all backups in the cluster. Then it selects the best candidate, using its knowledge of where it has already allocated segment replicas and information about the speed of each backup’s disk. The best backup is the one that can read its share of the master’s segment replicas most quickly from disk during recovery. A backup is rejected if it is in the same rack as the master or any other replica for the current segment. Once a backup has been selected, the master contacts that backup to reserve space for the segment. At this point the backup can reject the request if it is overloaded, in which case the master selects another candidate.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Advantages of randomization + refinement:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eliminate behavior: all masters choosing the same backups in a lock-step fashion&lt;/li&gt;
&lt;li&gt;provides a solution nearly as optimal as a centralized manager&lt;/li&gt;
&lt;li&gt;make segment distribution nearly uniform&lt;ul&gt;
&lt;li&gt;compensate for each machine difference: more powerful machine, high disk speed, more likely to be selected&lt;/li&gt;
&lt;li&gt;handles the entry of new backups gracefully: new machine, less workload, more likely to be selected&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="remarks-thoughts"&gt;Remarks &amp;amp; Thoughts&lt;/h2&gt;
&lt;p&gt;Each segment is randomly shuffled to multiple backups and recovery is constructed in parallel, which reminds me of the MapReduce. Segments are
distributed uniformly across backups, which mirrors chunking the data evenly in Map phase. The recovery from multiple recovery masters and
each recovery master only done part of the whole need-to-be-recovered data, which reminds me of Reduce phase. Even Prof. John Ousterhout in the &lt;a href="https://www.youtube.com/watch?v=lcUvU3b5co8"&gt;video&lt;/a&gt; thinks that MapReduce almost solve their problem. &lt;/p&gt;
&lt;p&gt;&lt;img alt="map reduce" class="img-responsive" src="/images/mapreduce.png"/&gt;&lt;/p&gt;
&lt;p&gt;This finding is quite atonishing to me because &lt;a href="https://static.googleusercontent.com/media/research.google.com/en//archive/mapreduce-osdi04.pdf"&gt;MapReduce paper&lt;/a&gt;
comes out in 2004 and RAMCloud comes out in 2011. If we take a slightly different angle to look at prior work, we may find something new. That’s provoking for
me in terms of research.&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.stanford.edu/~ouster/cgi-bin/papers/ramcloud-recovery.pdf"&gt;Fast Crash Recovery in RAMCloud&lt;/a&gt;, &lt;a href="https://ramcloud.atlassian.net/wiki/spaces/RAM/pages/6848659/RAMCloud+Presentations"&gt;slides&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=lcUvU3b5co8"&gt;video on paper&lt;/a&gt;,
&lt;a href="https://www.youtube.com/channel/UCqnEwnxxNoHwCwY5W5kfGVA/videos"&gt;videos on details of paper&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.puncsky.com/blog/2012/12/13/fast-crash-recovery-in-ramcloud/"&gt;Tian Pan’s Blog on RAMCloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ongardie.net/var/blurbs/pubs/ramcloud-tocs15.pdf"&gt;The RAMCloud Storage System&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The coordinator will use ZooKeeper to store its configuration information, which consists of a list of active storage servers along with the tablets they manage. ZooKeeper本身是一个非常牢靠的记事本，用于记录一些概要信息。Hadoop依靠这个记事本来记录当前哪些节点正在用，哪些已掉线，哪些是备用等，以此来管理机群。 &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="system"></category><category term="papers"></category><category term="storage"></category><category term="distributed systems"></category></entry><entry><title>"PebblesDB: Building Key-Value Stores using Fragmented Log-Structured Merge Trees"</title><link href="https://zhu45.org/posts/2018/Mar/30/pebblesdb-building-key-value-stores-using-fragmented-log-structured-merge-trees/" rel="alternate"></link><published>2018-03-30T00:45:00+08:00</published><updated>2018-03-30T00:45:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-30:/posts/2018/Mar/30/pebblesdb-building-key-value-stores-using-fragmented-log-structured-merge-trees/</id><summary type="html">&lt;p&gt;&amp;ldquo;PebblesDB: Building Key-Value Stores using Fragmented Log-Structured Merge Trees&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#background"&gt;Background&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#key-value-store-operations"&gt;Key-Value Store Operations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lsm"&gt;LSM&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#lsm-operations"&gt;LSM Operations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#write-amplification-root-cause"&gt;Write Amplification: Root Cause&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#fragmented-log-structured-merge-tree-flsm"&gt;Fragmented Log-Structured Merge Tree (FLSM)&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#guards"&gt;Guards&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#selecting-guards"&gt;Selecting Guards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#inserting-and-deleting-guards"&gt;Inserting and Deleting Guards&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#flsm-operations"&gt;FLSM Operations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#limitations"&gt;Limitations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#building-pebblesdb-over-flsm"&gt;Building PebblesDB over FLSM&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#improving-read-performance"&gt;Improving Read Performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#improving-range-query-performance"&gt;Improving Range Query Performance&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-reading"&gt;Further Reading&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;— 05/22/18 UPDATE —&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;I write this post when I start to read system papers and even before I read through PebblesDB’s code. 
My system paper reading skill is lacking and I cannot fully grasp the essence of the paper back then. Please
jump to the &lt;a href="#remarks"&gt;Remarks&lt;/a&gt; section for a concise summary of LSM and FLSM (PebblesDB’s
data structure). The other sections are filled with unnecessary details and they are helpful only when you
want to &lt;a href="https://github.com/xxks-kkk/HyperPebblesDB"&gt;build something&lt;/a&gt; based on the paper’s implementation.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;One fundamental problem is the high write amplification of key-value stores for write-intensive workloads. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write amplification = the ratio of total write IO performed by the store to the total user written&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;High write amplification is bad&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;increases the load on storage devices such as SSDs, which have limited write cycles before the bit error rate becomes unacceptable&lt;/li&gt;
&lt;li&gt;results in frequent device wear out and high storage &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;reduces write throughput&lt;/p&gt;
&lt;p&gt;RocksDB write throughput is 10% of read throughput thanks to write amplifcation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;虽然LSM的写放大最近被研究很多，但是就写放大本身而言，是一个很古老的问题。在计算机体系中，如果相邻两层的处理单元不一致或者应用对一致性等有特殊的需求，就很可能出现写放大问题。比如CPU cache和内存cell，文件系统block和磁盘扇区，数据库block和文件系统block，数据库redo/undo，文件系统journal等.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Reduce write amplification inuition: log-structured merge trees (LSM) data structures is the root cause to the write amplification&lt;/p&gt;
&lt;p&gt;LSM stores maintain data in sorted order on storage, enabling efficient querying of data. However, when new data is inserted into an LSM-store, existing data is rewritten to maintain the sorted order, resulting in large amounts of write IO.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Key idea to reduce write amplification:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Combine LSM with skip list: fragmenting data into smaller chunks that are organized using guards on storage. Guards allow FLSM to find keys efficiently. &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Why the idea can improve write throughput intuitively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write operations on LSM stores are often stalled or blocked while data is compacted (rewritten for better read performance); by drastically reducing write IO, FLSM makes compaction signi￿cantly faster, thereby increasing write throughput.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="background"&gt;Background&lt;/h2&gt;
&lt;h3 id="key-value-store-operations"&gt;Key-Value Store Operations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;get(key)&lt;/code&gt; operation returns the latest value associated with key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;put(key, value)&lt;/code&gt; operation stores the mapping from key to value in the store. If key was already present in the store, its associated value is updated.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some key-value stores such as LevelDB provide an iterator over the entire key-value store. &lt;code&gt;it.seek(key)&lt;/code&gt; positions the iterator &lt;code&gt;it&lt;/code&gt; at the smallest key 
&lt;code&gt;&amp;gt;= key&lt;/code&gt;. The &lt;code&gt;it.next()&lt;/code&gt; call moves &lt;code&gt;it&lt;/code&gt; to the next key in sequence. The &lt;code&gt;it.value()&lt;/code&gt; call returns the value associated with the key at the current iterator position.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;range_query(key1, key2)&lt;/code&gt; operation returns all key-value pairs falling within the given range. Range queries are often implemented by doing a &lt;code&gt;seek()&lt;/code&gt; to &lt;code&gt;key1&lt;/code&gt; and doing &lt;code&gt;next()&lt;/code&gt; calls until the iterator passes &lt;code&gt;key2&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="lsm"&gt;LSM&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;LSM &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt; is treated as a replacement for B+ Tree&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Why not B+ Tree:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;low write throughput: B+ Trees are a poor fit for write-intensive workloads: updating the tree requires multiple random writes (10-100X slower than sequential writes).&lt;/li&gt;
&lt;li&gt;high write amplification (61X write amplification)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The log-structured merge trees (LSM) data structure takes advantage of high sequential bandwidth by only writing sequentially to storage. 
Writes are batched together in memory and written to storage as a sequential log (termed an &lt;strong&gt;sstable&lt;/strong&gt;). Each sstable contains a sorted sequence of keys.&lt;/p&gt;
&lt;p&gt;&lt;img alt="sstable" class="img-responsive" src="https://zhu45.org/images/sstable.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;A “Sorted String Table” then is exactly what it sounds like, it is a file which contains a set of arbitrary, sorted key-value pairs inside. Duplicate keys are fine, there is no need for “padding” for keys or values, and keys and values are arbitrary blobs. Read in the entire file sequentially and you have a sorted index. Optionally, if the file is very large, we can also prepend, or create a standalone &lt;code&gt;key:offset&lt;/code&gt; index for fast access. That’s all an SSTable is: very simple, but also a very useful way to exchange large, sorted data segments.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sstables on storage are organized as hierarchy of &lt;strong&gt;levels&lt;/strong&gt;. Each level contains multiple sstables, and has a maximum size for its sstables.&lt;/p&gt;
&lt;p&gt;In a 5-level LSM, Level 0 is the lowest level and Level 5 is the highest level. The amount of data (and the number of sstables) in each level increases as the levels get higher. The last level in an LSM may contain hundreds of gigabytes. Application data usually flows into the lower levels and is then compacted into the higher levels. The lower levels are usually cached in memory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LSM maintains the following invariant at each level: all sstables contain disjoint sets of keys.&lt;/p&gt;
&lt;p&gt;For example, a level might contain three sstables: &lt;span class="math"&gt;\([1 \dots 6], [8 \dots 12]\)&lt;/span&gt;, and &lt;span class="math"&gt;\([100 \dots 105]\)&lt;/span&gt;. Each key will be present in exactly one sstable on a given level. As a result, locating a key requires only two binary searches: one binary search on the starting keys of sstables (maintained separately) to locate the correct sstable and another binary search inside the sstable to find the key. If the search fails, the key is not present in that level.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="lsm-operations"&gt;LSM Operations&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;get()&lt;/code&gt; returns the latest value of the key&lt;/p&gt;
&lt;p&gt;Since the most recent data will be in lower levels, the key-value store searches for the key level by level, starting from Level 0; if it finds the key, it returns the value. Each key has a sequence number that indicates its version. Finding the key at each level requires reading and searching exactly one sstable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;seek()&lt;/code&gt; and &lt;code&gt;next()&lt;/code&gt; require positioning an iterator over the entire key-value store. &lt;/p&gt;
&lt;p&gt;implemented using multiple iterators (one per level); each iterator is first positioned inside the appropriate sstable in each level, and the iterator results are merged. The &lt;code&gt;seek()&lt;/code&gt; requires finding the appropriate sstables on each level, and positioning the sstable iterators. The results of the sstable iterators are merged (by identifying the smallest key) to position the key-value store iterator. The &lt;code&gt;next()&lt;/code&gt; operation simply advances the correct sstable iterator, merges the iterators again, and re-positions the key-value store iterator.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;put()&lt;/code&gt; writes the key-value pair, along with a monotonically increasing sequence number, to an in-memory skip list called the &lt;strong&gt;memtable&lt;/strong&gt;. When the memtable reaches a certain size, it is written to storage as a sstable at Level 0. When each level contains a threshold number of files, it is compacted into the next level. &lt;/p&gt;
&lt;p&gt;Assume Level 0 contains &lt;code&gt;[2, 3]&lt;/code&gt; and &lt;code&gt;[10, 12]&lt;/code&gt; sstables. If Level 1 contains &lt;code&gt;[1,4]&lt;/code&gt; and &lt;code&gt;[9, 13]&lt;/code&gt; sstables, then during compaction, Level 1 sstables are rewritten as &lt;code&gt;[1, 2, 3, 4]&lt;/code&gt; and &lt;code&gt;[9, 10, 12, 13]&lt;/code&gt;, merging the sstables from Level 0 and Level 1. Compacting sstables reduces the total number of sstables in the key-value store and pushes colder data into higher levels. The lower levels are usually cached in memory, thus leading to faster reads of recent data.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Think about &lt;em&gt;memtable&lt;/em&gt; as in-memory SSTable.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Updating or deleting keys in LSM-based stores does not update the key in place, since all write IO is sequential. Instead, the key is inserted once again into the memtable with a higher sequence number; a delete key is inserted again with a special flag (often called a &lt;strong&gt;tombstone&lt;/strong&gt; flag). Due to the higher sequence number, the latest version of the flag will be returned by the store to the user.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="write-amplification-root-cause"&gt;Write Amplification: Root Cause&lt;/h3&gt;
&lt;p&gt;&lt;img alt="sstable" class="img-responsive" src="https://zhu45.org/images/lsm-root-cause.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The root cause for write amplification: multiple rewrites of sstables during compaction. In other words, sstables can be rewritten multiple
times when new data is compacted into them.&lt;/p&gt;
&lt;p&gt;For example, when compaction happens from &lt;span class="math"&gt;\(t_1\)&lt;/span&gt; to &lt;span class="math"&gt;\(t_2\)&lt;/span&gt;, sstable with &lt;code&gt;[1,100]&lt;/code&gt; has to be rewritten to &lt;code&gt;[1,10,100]&lt;/code&gt; and
sstable with &lt;code&gt;[200,400]&lt;/code&gt; has to be rewritten as &lt;code&gt;[200,210,400]&lt;/code&gt; (i.e., We have to read &lt;code&gt;[10,210]&lt;/code&gt;, &lt;code&gt;[1,100]&lt;/code&gt;, &lt;code&gt;[200,400]&lt;/code&gt; out of levels, merge sort them, and write them back.)&lt;/p&gt;
&lt;p&gt;L0文件里面包含的key同时在L1层的多个文件（甚至全部文件）被包含，所以如果想把L0下推到L1，那么就需要将整个L0/L1文件内的key读出来重新排序写入到L1。典型情况下，L0数据量是L1的1/10，为了这么点数据量重写所有数据显然不划算。L1…Ln道理类似&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;放大问题的本质是一个系统对“随时全局有序”的需求有多么的强烈。所谓随时，就是任何的写入都不能导致系统无序；所谓全局，即系统内任意元单位之间都要保持有序。B-Tree系列是随时全局有序的典型代表，而Fractal tree打破了全局的约束，允许局部无序，提升了随机写能力；LSM系列进一步打破了随时的约束，允许通过后台的compaction来整理排序。在LSM这种依靠后台整理来保序的系统里面，系统对序的要求越强烈，写放大越严重。PebblesDB针对写放大提出的解决方案是弱化全局有序的约束，其将每一层进行分段，每个段称为一个guard，guard之间没有重叠的key，且每层的guard之间要求保序，但是guard内部可以无序。&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="fragmented-log-structured-merge-tree-flsm"&gt;Fragmented Log-Structured Merge Tree (FLSM)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FLSM counters mutlple rewrites of sstables by fragmenting sstables into smaller units. Instead of rewriting the sstable, FLSM’s compaction simply appends a new sstable fragment to the next level. Doing so ensures that data is written exactly once in most levels&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Here, I’m guessing “append” really means pointer change from one node to another. Thus, the only time IO is performed when the data is first written
to sstable at a level.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="guards"&gt;Guards&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the classical LSM, each level contains sstables with disjoint key ranges (i.e., each key will be present in exactly one sstable). Maintaining this invariant is the root cause of write amplification, as it forces data to be rewritten in the same level.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The FLSM data structure discards this invariant: each level can contain multiple sstables with overlapping key ranges, so that a key may be present in multiple sstables. To quickly find keys in each level, FLSM organizes the sstables into guards (similar to level concept in skip list)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each level contains multiple guards. Guards divide the key space (for that level) into disjoint units. Each guard &lt;span class="math"&gt;\(G_i\)&lt;/span&gt; has an associated key &lt;span class="math"&gt;\(K_i\)&lt;/span&gt;, chosen from among keys inserted into the FLSM. Each level in the FLSM contains more guards than the level above it; the guards get progressively more fine-grained as the data gets pushed deeper and deeper into the FLSM. As in a skip-list, if a key is a guard at a given level &lt;span class="math"&gt;\(i\)&lt;/span&gt;, it will be a guard for all levels &lt;span class="math"&gt;\(&amp;gt; i\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each guard has a set of associated sstables. Each sstable is sorted. If guard &lt;span class="math"&gt;\(G_i\)&lt;/span&gt; is associated with key &lt;span class="math"&gt;\(K_i\)&lt;/span&gt; and guard &lt;span class="math"&gt;\(G_{i+1}\)&lt;/span&gt; with &lt;span class="math"&gt;\(K_{i+1}\)&lt;/span&gt;, an sstable with keys in the range &lt;span class="math"&gt;\([K_i,K_{i+1})\)&lt;/span&gt; will be attached to &lt;span class="math"&gt;\(G_i\)&lt;/span&gt; . Sstables with keys smaller than the first guard are stored in a special sentinel guard in each level. The last guard&lt;span class="math"&gt;\(G_n\)&lt;/span&gt; in the level stores all sstables with keys &lt;span class="math"&gt;\(\ge K_n\)&lt;/span&gt; . Guards within a level never have overlapping key ranges. Thus, to find a key in a given level, only one guard will have to be examined.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In FLSM compaction, the sstables of a given guard are (merge) sorted and then fragmented (partitioned), so that each child guard receives a new sstable that fits into the key range of that child guard in the next level.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="guards" class="img-responsive" src="https://zhu45.org/images/guards.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Some observations about Figure 3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;code&gt;put()&lt;/code&gt; results in keys being added to the in-memory memtable (not shown). Eventually, the memtable becomes full, and is written as an sstable to Level 0. Level 0 does not have guards, and collects together recently written sstables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each level has a sentinel guard that is responsible for sstables with keys &amp;lt; than the first guard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Data inside an FLSM level is partially sorted: guards do not have overlapping key ranges, but the sstables attached to each guard can have overlapping key ranges.（In level 3 Guard: 5, &lt;code&gt;[5,35,40]&lt;/code&gt; and &lt;code&gt;[7]&lt;/code&gt; are overlapping)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h4 id="selecting-guards"&gt;Selecting Guards&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the worst case, if one guard contains all sstables, reading and searching such a large guard (and all its constituent sstables) would cause an un-acceptable increase in latency for reads and range queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;guards are not selected statically; guards are selected probabilistically from inserted keys, preventing skew.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Current selection policy: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if the guard probability is 1/10, one in every 10 inserted keys will be randomly selected to be a guard.&lt;/li&gt;
&lt;li&gt;The guard probability is designed to be lowest at Level 1 (which has the fewest guards), and it increases with the level number (as higher levels have more guards)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;if a key &lt;span class="math"&gt;\(K\)&lt;/span&gt; is selected as a guard in level i, it becomes a guard for all higher levels &lt;span class="math"&gt;\(i + 1, i + 2\)&lt;/span&gt; etc. The guards in level &lt;span class="math"&gt;\(i + 1\)&lt;/span&gt; are a strict superset of the guards in level &lt;span class="math"&gt;\(i\)&lt;/span&gt; (in Figure 3, key 5 is chosen as a guard for Level 1; therefore it is also a guard for levels 2 and 3.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="inserting-and-deleting-guards"&gt;Inserting and Deleting Guards&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Guards are inserted asynchronously into FLSM&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When guards are selected, they are added to an in-memory set termed the &lt;em&gt;uncommitted guards&lt;/em&gt;. Sstables are not partitioned on storage based on (as of yet) uncommitted guards; as a result, FLSM reads are performed as if these guards did not exist. At the next compaction cycle, sstables are partitioned and compacted based on both old guards and uncommitted guards; any sstable that needs to be split due to an uncommitted guard is compacted to the next level. At the end of compaction, the uncommitted guards are persisted on storage and added to the full set of guards. Future reads will be performed based on the full set of guards.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;guard deletion was not required&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Guard deletion is also performed asynchronously similar to guard insertion. Deleted guards are added to an in-memory set. At the next compaction cycle, sstables are re-arranged to account for the deleted guards. Deleting a guard G at level i is done lazily at compaction time. During compaction, guard G is deleted and sstables belonging to guard G will be partitioned and appended to either the neighboring guards in the same level i or child guards in level i + 1. Compaction from level i to i + 1 proceeds as normal (since G is still a guard in level i + 1). At the end of compaction, FLSM persists metadata indicating G has been deleted at level i. If required, the guard is deleted in other levels in a similar manner. Note that if a guard is deleted at level i, it should be deleted at all levels &amp;lt; i; FLSM can choose whether to delete the guard at higher levels &amp;gt; i.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="flsm-operations"&gt;FLSM Operations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;get()&lt;/code&gt; operation first checks the in-memory memtable. If the key is not found, the search continues level by level, starting with level 0. During the search, if the key is found, it is returned immediately; To check if a key is present in a given level, binary search is used to find the single guard that could contain the key. Once the guard is located, its sstables are searched for the key. Thus, in the worst case, a &lt;code&gt;get()&lt;/code&gt; requires reading one guard from each level, and all the sstables of each guard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Range queries require collecting all the keys in the given range. FLSM first identifies the guards at each level that intersect with the given range. Inside each guard, there may be multiple sstables that intersect with the given range; a binary search is performed on each sstable to identify the smallest key overall in the range. Identifying the next smallest key in the range is similar to the merge procedure in merge . When the end of range query interval is reached, the operation is complete, and the result is returned to the user.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;put()&lt;/code&gt; adds data to an in-memory memtable. When the memtable gets full, it is written as a sorted sstable to Level 0. When each level reaches a certain size, it is compacted into the next level. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Similar to LSM, updating or deleting a key involves inserting the key into the store with an updated sequence number or a deletion flag respectively. the deletion of the key does not result in deletion of the related guard; deleting a guard will involve a signi￿cant amount of compaction work. Thus, empty guards are possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compaction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The sstables in the guard are first (merge) sorted and then partitioned into new sstables based on the guards of the next level; the new sstables are then attached to the correct guards. &lt;/p&gt;
&lt;p&gt;Assume a guard at Level 1 contains keys &lt;code&gt;[1, 20, 45, 101, 245]&lt;/code&gt;. If the next level has guards 1, 40, and 200, the sstable will be partitioned into three sstables containing &lt;code&gt;[1, 20]&lt;/code&gt;, &lt;code&gt;[45, 101]&lt;/code&gt;, and &lt;code&gt;[245]&lt;/code&gt; and attached to guards 1, 40, and 200 respectively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;New sstables are simply added to the correct guard in the next level.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two exceptions to no-rewrite rule:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;at the highest level (e.g,. Level 5) of FLSM, the sstables have to be rewritten during compaction; there is no higher level for the sstables to be partitioned and attached to.&lt;/li&gt;
&lt;li&gt;for the second-highest level (e.g,. Level 4), FLSM will rewrite an sstable into the same level if the alternative is to merge into a large sstable in the highest level &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="limitations"&gt;Limitations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Since &lt;code&gt;get()&lt;/code&gt; and range query operations need to examine all sstables within a guard, the latency of these operations is increased in comparison to LSM.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="building-pebblesdb-over-flsm"&gt;Building PebblesDB over FLSM&lt;/h2&gt;
&lt;p&gt;Due to the limitation of FLSM, several existing techniques are applied to improve read performance (i.e., &lt;code&gt;put()&lt;/code&gt; and range query operations)&lt;/p&gt;
&lt;h3 id="improving-read-performance"&gt;Improving Read Performance&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cause: &lt;code&gt;get()&lt;/code&gt; in FLSM causes all the sstables of one guard in each level to be examined. In contrast, in LSM, exactly one sstable per level needs to be examined.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Improvement technique:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sstable Bloom Filters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A Bloom filter is a space-efficient probabilistic data structure used to test whether an element is present in a given set in constant time&lt;/li&gt;
&lt;li&gt;A bloom filter can produce false positives, but not false negatives (i.e., the key is in sstables but bloom filters say no)&lt;/li&gt;
&lt;li&gt;PebblesDB attaches a bloom filter to each sstable to e￿ciently detect if a given key could be present in the sstable. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="improving-range-query-performance"&gt;Improving Range Query Performance&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Cause: require examining all the sstables of a guard for FLSM. Since LSM stores examine only one sstable per level, FLSM stores have significant overhead for range queries&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Improvement technique:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seek-Based Compaction&lt;/li&gt;
&lt;li&gt;Parallel Seek&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;p&gt;Log-structured Merge Tree (LSM) is a data structure that is used to provide good write performance by leverage log organizations.
In details, write to LSM-based storage system is first written to in-memory log called &lt;em&gt;MemTable&lt;/em&gt;
by appending the corresponding key-value pair at the end of log. Doing the write through appending is
the key differentiator from the B-tree-based storage system as we are doing the sequential write instead of
the random update, which can reduce write amplification and improve the write performance. &lt;/p&gt;
&lt;p&gt;To improve the read performance and make the system scalable
to the large datasets, LSM-based storage system organizes their logs into levels. The first layer
(numbered as 0), which
&lt;em&gt;MemTable&lt;/em&gt; is stored in memory. All the logs (&lt;em&gt;sstables&lt;/em&gt;) in the rest levels are written to the persistent storage devices. 
Acceptable read performance is maintained by lowering down the number of logs. 
This is done by &lt;em&gt;compactions&lt;/em&gt;, which merges the logs in the upper level into the lower level (i.e.,
merging sstables from level 1 to level 2). However, there is problem with the merging process as we
need to read both logs from the upper level and lower level into memory and perform the merge. This mechanism
naturally introduces the write amplifcation effect, which decreases the write performance.&lt;/p&gt;
&lt;p&gt;&lt;img alt="flsm compaction process illustration" class="img-responsive" src="https://zhu45.org/images/guard-compaction.png"/&gt;&lt;/p&gt;
&lt;p&gt;To combat write amplification, Fragmented Log-Structured Merge Trees (FLSM) and its implementation &lt;em&gt;PebblesDB&lt;/em&gt; are proposed. 
The key idea is shown in picture above. FLSM uses &lt;em&gt;guard&lt;/em&gt;, which
can be thought of as the key for a collection of logs. the keys in the collection of logs have to be 
in the range between the current guard’s key and the previous guard’s key. During the compaction, the 
the log in the upper level is split across the guard keys in the lower level. In the example shown
above, 10 and 80 from level 1 is split to 10 in guard 60 and 80 to guard 100 in level 2.
As one can see, this split and append avoids reading the data from lower level (e.g., level 2), which reduces
the write amplification and improve the write performance. Read performance stays still thanks to the guard 
as we can first search guard key and then logs within the guard to locate the corresponding value for the 
given key. &lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.cs.utexas.edu/~vijay/papers/sosp17-pebblesdb.pdf"&gt;PebblesDB: Building Key-Value Stores using Fragmented Log-Structured Merge Trees&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.igvita.com/2012/02/06/sstable-and-log-structured-storage-leveldb/"&gt;SSTable and Log Structured Storage: LevelDB&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://zhuanlan.zhihu.com/p/32225460"&gt;PebblesDB读后感&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="further-reading"&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.cs.utexas.edu/~vijay/papers/pebblesdb-sosp17-slides.pdf"&gt;PebblesDB Slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide"&gt;RocksDB Tuning Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ristret.com/s/gnd4yr/brief_history_log_structured_merge_trees"&gt;A Brief History of Log Structured Merge Trees&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://www.cs.cmu.edu/~ckingsf/bioinfo-lectures/skiplists.pdf"&gt;CMU slides&lt;/a&gt;, &lt;a href="http://igoro.com/archive/skip-lists-are-fascinating/"&gt;this post&lt;/a&gt;, and
&lt;a href="https://www.ics.uci.edu/~pattis/ICS-23/lectures/notes/Skip%20Lists.pdf"&gt;UCI reading&lt;/a&gt; give an intuitive introduction to skip list. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;&lt;a href="http://www.benstopford.com/2015/02/14/log-structured-merge-trees/"&gt;This post&lt;/a&gt; contains a plenty of good pointers to get familiar with LSM. Also,
&lt;a href="http://webee.technion.ac.il/~idish/ftp/clsm.pdf"&gt;cLSM paper&lt;/a&gt; (section 2.3 and Figure 2) also provides a good summary. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="papers"></category><category term="storage"></category><category term="log-structured merge tree"></category></entry><entry><title>"BLEU: a Method for Automatic Evaluation of Machine Translation"</title><link href="https://zhu45.org/posts/2018/Mar/28/bleu-a-method-for-automatic-evaluation-of-machine-translation/" rel="alternate"></link><published>2018-03-28T01:24:00+08:00</published><updated>2018-03-28T01:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-28:/posts/2018/Mar/28/bleu-a-method-for-automatic-evaluation-of-machine-translation/</id><summary type="html">&lt;p&gt;&amp;ldquo;BLEU: a Method for Automatic Evaluation of Machine Translation&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-baseline-bleu-metric"&gt;The Baseline BLEU Metric&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#modified-n-gram-precision"&gt;Modified n-gram precision&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks-on-bleu"&gt;Remarks on BLEU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How does one measure translation performance? The central idea: &lt;em&gt;The closer a machine translation is to a professional human translation, the better it is.&lt;/em&gt;
Thus requires:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a numerical “translation closeness” metric&lt;/li&gt;
&lt;li&gt;a corpus of good quality human reference translations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fashion the closeness metric after &lt;em&gt;word error rate&lt;/em&gt; metric used by the speech recognition community&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The main idea is to use a weighted average of variable length phrase matches against the reference translations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-baseline-bleu-metric"&gt;The Baseline BLEU Metric&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example 1:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Candidate 1: It is a guide to action which ensures that the military always obeys the commands of the party.&lt;/li&gt;
&lt;li&gt;Candidate 2: It is to insure the troops forever hearing the activity guidebook that party direct.&lt;/li&gt;
&lt;li&gt;Reference 1: It is a guide to action that ensures that the military will forever heed Party commands.&lt;/li&gt;
&lt;li&gt;Reference 2: It is the guiding principle which guarantees the military forces always being under the command of the Party.&lt;/li&gt;
&lt;li&gt;Reference 3: It is the practical guide for the army always to heed the directions of the party.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Candidate 1 is better than Candidate 2 because Candidate 1 shares many words and phrases with these three reference translations, while Candidate 2 does not.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Candidate 1 shares “It is a guide to action” with Reference 1, “which” with Reference 2, “ensures that the military” with Reference 1, 
“always” with References 2 and 3, “commands” with Reference 1, and finally “of the party” with Reference 2 (all ignoring capitalization). 
In contrast, Candidate 2 exhibits far fewer matches, and their extent is less.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Rank Candidate 1 higher than Candidate 2 simply by comparing n-￼￼gram matches between each candidate translation and the reference translations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The primary programming task for a BLEU implementor is to compare n-grams of the candidate with the n-grams of the reference translation and count the number of matches. These matches are position-independent. The more the matches, the better the candidate translation is.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="modified-n-gram-precision"&gt;Modified n-gram precision&lt;/h3&gt;
&lt;p&gt;We compute unigram matches to illustrate the idea.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example 2:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Candidate: the the the the the the the. &lt;/li&gt;
&lt;li&gt;Reference 1: The cat is on the mat. &lt;/li&gt;
&lt;li&gt;Reference 2: There is a cat on the mat.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Precision&lt;/em&gt; (# candidate translation words (unigrams) which occur in any reference translation / the total number of words in the candidate translation) 
doesn’t work: MT systems can overgenerate “reasonable” words, resulting in improbable, but high-precision, translations like Example 2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Intuition: a reference word should be considered exhausted after a matching candidate word is identified. We formalize this intuition as the
&lt;em&gt;modified unigram precision&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How to compute &lt;em&gt;modified unigram precision&lt;/em&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;counts the maximum number of times a word occurs in any single reference translation&lt;/li&gt;
&lt;li&gt;one clips the total count of each candidate word by its maximum reference count&lt;/li&gt;
&lt;li&gt;adds these clipped counts (i.e., &lt;span class="math"&gt;\(\text{Count}_{clip}\)&lt;/span&gt;) up, and divides by the total (unclipped) number of candidate words.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\text{Count}_{clip} = \min(\text{Count}, \text{Max_Ref_Count})\)&lt;/span&gt;. In other words, one truncates each word’s count, if necessary, to not exceed the largest count observed in any single reference for that word.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Examples on &lt;em&gt;modified unigram precision&lt;/em&gt; calculation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Example 2: modified unigram precision is &lt;span class="math"&gt;\(2/7\)&lt;/span&gt;, even though its standard unigram precision is &lt;span class="math"&gt;\(7/7\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Example 1: Candidate 1 achieves a modified unigram precision of &lt;span class="math"&gt;\(17/18\)&lt;/span&gt;; whereas Candidate 2 achieves a modified unigram precision of &lt;span class="math"&gt;\(8/14\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Let’s calculate &lt;span class="math"&gt;\(17/18\)&lt;/span&gt;. The counts shown below. For word “the”, “the” appears 3 times in Candidate 1 and 4 comes from
max(# “the” in ref1, # “the” in ref2, # “the” in ref3) = max(1,4,4). &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| word          | it | is | a | guide | to | action | which | ensures | that | the | miltary | always | obeys | commands | of | party | SUM |
|---------------|----|----|---|-------|----|--------|-------|---------|------|-----|---------|--------|-------|----------|----|-------|-----|
| count         | 1  | 1  | 1 | 1     | 1  | 1      | 1     | 1       | 1    | 3   | 1       | 1      | 1     | 1        | 1  | 1     | 18  |
| Max_Ref_Count | 1  | 1  | 1 | 1     | 1  | 1      | 1     | 1       | 2    | 4   | 1       | 1      | 0     | 1        | 1  | 1     |     |
| Count_clip    | 1  | 1  | 1 | 1     | 1  | 1      | 1     | 1       | 1    | 3   | 1       | 1      | 0     | 1        | 1  | 1     | 17  |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;How to compute Modified n-gram precision (computed similarly for any n): &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;all candidate n-gram counts and their corresponding maximum reference counts are collected. &lt;/li&gt;
&lt;li&gt;The candidate counts are clipped by their corresponding reference maximum value, summed, and divided by the total number of candidate n-grams.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Examples on &lt;em&gt;modified bigram precision&lt;/em&gt; calculation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Example 1: Candidate 1 achieves a modified bigram precision of &lt;span class="math"&gt;\(10/17\)&lt;/span&gt;, whereas the lower quality Candidate 2 achieves a modified bigram precision of &lt;span class="math"&gt;\(1/13\)&lt;/span&gt;. &lt;/li&gt;
&lt;li&gt;Example 2: the (implausible) candidate achieves a modified bigram precision of 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modified n-gram precision on corpus&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We first compute the n-gram matches sentence by sentence. Next, we add the clipped n-gram counts for all the candidate sentences and divide by the number of candidate n-grams in the test corpus to compute a modified precision score, &lt;span class="math"&gt;\(p_n\)&lt;/span&gt;, for the entire test corpus.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="modified n-gram precision on corpus" class="img-responsive" src="https://zhu45.org/images/bleu-corpus.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We want to combine all n-gram precision on corpus (i.e., &lt;span class="math"&gt;\(n=1,2,3,4\)&lt;/span&gt;) together into a single number metric. the modified n-gram precision decays roughly exponentially with n: the modified unigram precision is much larger than the modified bigram precision which in turn is much bigger than the modified trigram precision. BLEU uses the geometric mean of the modified n-gram precisions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modified n-gram precision alone fails to enforce the proper translation length. Candidate translations longer than their references are already penalized by the modified n-gram precision measure. However, candidate translations shorter than their references are not penalized.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example 3:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Candidate: of the&lt;/li&gt;
&lt;li&gt;Reference 1: It is a guide to action that ensures that the military will forever heed Party commands.&lt;/li&gt;
&lt;li&gt;Reference 2: It is the guiding principle which guarantees the military forces always being under the command of the Party.&lt;/li&gt;
&lt;li&gt;Reference 3: It is the practical guide for the army always to heed the directions of the party.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Because this candidate is so short compared to the proper length, one expects to find inflated precisions: the modified unigram precision is 2/2, and the modified bigram precision is 1/1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Traditional recall is not a good measure to enforce proper length translation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Example 4:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Candidate 1: I always invariably perpetually do.&lt;/li&gt;
&lt;li&gt;Candidate 2: I always do.&lt;/li&gt;
&lt;li&gt;Reference 1: I always do.&lt;/li&gt;
&lt;li&gt;Reference 2: I invariably do. &lt;/li&gt;
&lt;li&gt;Reference 3: I perpetually do.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The first candidate recalls more words from the references, but is obviously a poorer translation than the second candidate&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sentence ￼￼￼￼￼￼￼brevity penalty&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We wish to make the brevity penalty 1.0 when the candidate’s length is the same as any reference translation’s length.&lt;/li&gt;
&lt;li&gt;if there are three references with lengths 12, 15, and 17 words and the candidate translation is a terse 12 words, we want the brevity penalty to be 1. &lt;/li&gt;
&lt;li&gt;We call the closest reference sentence length the “&lt;em&gt;best match length&lt;/em&gt;.”&lt;/li&gt;
&lt;li&gt;we compute the brevity penalty over the entire corpus to al- low some freedom at the sentence level.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compute sentence brevity penalty&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Compute the test corpus’ effective reference length, &lt;span class="math"&gt;\(r\)&lt;/span&gt;, by summing the best match lengths for each candidate sentence in the corpus. &lt;/li&gt;
&lt;li&gt;We choose the brevity penalty to be a decaying exponential in &lt;span class="math"&gt;\(r/c\)&lt;/span&gt;, where &lt;span class="math"&gt;\(c\)&lt;/span&gt; is the total length of the candidate translation corpus.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Put everything together to calculate BLEU&lt;/p&gt;
&lt;p&gt;We take the geometric mean of the test corpus’ modified precision scores and then multiply the result by an exponential brevity penalty factor.
We first compute the geometric average of the modified n-gram precisions, &lt;span class="math"&gt;\(p_n\)&lt;/span&gt;, using n-grams up to length &lt;span class="math"&gt;\(N\)&lt;/span&gt; and positive weights &lt;span class="math"&gt;\(w_n\)&lt;/span&gt; summing to one.
Next, let &lt;span class="math"&gt;\(c\)&lt;/span&gt; be the length of the candidate translation and &lt;span class="math"&gt;\(r\)&lt;/span&gt; be the effective reference corpus length. We compute the brevity penalty BP,&lt;/p&gt;
&lt;p&gt;&lt;img alt="BLEU calculation" class="img-responsive" src="https://zhu45.org/images/bleu-calc.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks-on-bleu"&gt;Remarks on BLEU&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This sort of modified n-gram precision scoring captures two aspects of translation: adequacy and fluency:&lt;/p&gt;
&lt;p&gt;A translation using the same words (1-grams) as in the references tends to satisfy adequacy. The longer n-gram matches account for fluency. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;BLEU only needs to match human judgment when averaged over a test corpus; scores on individual sentences will often vary from human judgments.
(For example, a system which produces the fluent phrase “East Asian economy” is penalized heavily on the longer n-gram precisions if all the references happen to read “economy of East Asia.”)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The BLEU metric ranges from 0 to 1. Few translations will attain a score of 1 unless they are identical to a reference translation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;the more reference translations per sentence there are, the higher the score is.&lt;/li&gt;
&lt;li&gt;We may use a big test corpus with a single reference translation, provided that the translations are not all from the same translator.&lt;/li&gt;
&lt;li&gt;BLEU has shown good performance for corpus-level comparisons over which a high number of n-gram matches exist. However, at a sentence-level the
n-gram matches for higher n rarely occur. As a result, BLEU performs poorly when comparing individual sentences.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.utexas.edu/~mooney/cs388/slides/mt.ppt"&gt;Mooney’s slides on MT&lt;/a&gt; has nice illustration of modified bigram precision
calculation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.aclweb.org/anthology/P02-1040.pdf"&gt;Bleu: a method for automatic evaluation of machine translation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/1504.00325.pdf"&gt;Microsoft COCO Captions: Data Collection and Evaluation Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="NLP"></category><category term="natural language processing"></category><category term="evaluation metrics"></category><category term="papers"></category></entry><entry><title>"Existential Consistency: Measuring and Understanding Consistency at Facebook"</title><link href="https://zhu45.org/posts/2018/Mar/08/existential-consistency-measuring-and-understanding-consistency-at-facebook/" rel="alternate"></link><published>2018-03-08T20:24:00+08:00</published><updated>2018-03-08T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-08:/posts/2018/Mar/08/existential-consistency-measuring-and-understanding-consistency-at-facebook/</id><summary type="html">&lt;p&gt;&amp;ldquo;Existential Consistency: Measuring and Understanding Consistency at Facebook&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#overview"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#facebooks-replicated-storage"&gt;Facebook’s Replicated Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#consistency-models"&gt;Consistency Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Facebook Study&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Analyzed a small portion of the Facebook traffic to the TAO graph system &lt;/li&gt;
&lt;li&gt;Analyzed what consistency models hold&lt;/li&gt;
&lt;li&gt;Analyzed when readers get anomalous results&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="facebooks-replicated-storage"&gt;Facebook’s Replicated Storage&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Facebook Data Model&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Graph Data Model&lt;/li&gt;
&lt;li&gt;Vertex: unique ID + data&lt;/li&gt;
&lt;li&gt;Edges: between two vertexes, contains data, indexed by source vertex&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Database&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Horizontally (i.e., row) sharded, geo-replicated database&lt;/li&gt;
&lt;li&gt;Each region has a full copy&lt;/li&gt;
&lt;li&gt;Each shard has a master which asynchronously updates the other regions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two-Level Cache&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Root cache sits in front of the database&lt;/li&gt;
&lt;li&gt;Leaf caches sit in front of the root caches&lt;/li&gt;
&lt;li&gt;Write-through caches&lt;/li&gt;
&lt;li&gt;Reads:&lt;ul&gt;
&lt;li&gt;progress down the stack in their local region on cache misses from leaf cache to root cache, and then to local database. 
  The cache-hit ratios are very high, so reads are typically served by the leaf caches.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Writes:&lt;ul&gt;
&lt;li&gt;They are synchronously routed through their leaf cache (1) to their local root cache (2) to the root-master cache (3), and to the master database shard (4) and back (5–8).&lt;/li&gt;
&lt;li&gt;Each of those caches applies the write when it forwards the database’s acknowledgment back towards the client.&lt;/li&gt;
&lt;li&gt;The root caches in the master (&lt;span class="math"&gt;\(6'\)&lt;/span&gt;) and originating regions (&lt;span class="math"&gt;\(7'\)&lt;/span&gt;) both asynchronously invalidate the other leaf caches in their region&lt;/li&gt;
&lt;li&gt;The database master asynchronously replicates the write to the slave regions (&lt;span class="math"&gt;\(5'\)&lt;/span&gt;). When a slave database in a region that did not originate the write receives it, the database asynchronously invalidates its root cache (&lt;span class="math"&gt;\(6''\)&lt;/span&gt;) that in turn asynchronously invalidates all its leaf caches (&lt;span class="math"&gt;\(7''\)&lt;/span&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="facebook replicated storage" class="img-responsive" src="/images/fb-storage.png"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="consistency-models"&gt;Consistency Models&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Local Consistency Models&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Local&lt;/strong&gt;: A consistency model, C, is local if the system as a whole provides C whenever each individual object provides C&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Linearizability&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linearizability is the strongest consistency model for non-transactional systems. &lt;/li&gt;
&lt;li&gt;Intuitively, linearizability ensures that each operation appears to take effect instantaneously at some point between when the client invokes the operation and it receives the response. &lt;/li&gt;
&lt;li&gt;More formally, linearizability dictates that there exists a total order over all operations in the system, and that this order is consistent with the real-time order of operations. &lt;ul&gt;
&lt;li&gt;If operation A completes before operation B begins, then A will be ordered before B. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Linearizability avoids anomalies by ensuring that writes take effect in some sequential order consistent with real time, and that reads always see the 
results of the most recently completed write.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Per-Object Sequential Consistency&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Per-object sequential consistency requires that there exists a legal, total order over all requests to each object that is consistent with client’s orders. &lt;/li&gt;
&lt;li&gt;Intuitively, there is one logical version of each object that progresses forward in time. &lt;/li&gt;
&lt;li&gt;Clients always see a newer version of an object as they interact with it. &lt;/li&gt;
&lt;li&gt;Different clients, however, may see different versions of the object.&lt;ul&gt;
&lt;li&gt;One client may be on version 100 of an object, while another client may see version 105.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Read-After-Write Consistency&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;when a write request has committed, all following read requests to that cache always reflect this write or later writes.&lt;/li&gt;
&lt;li&gt;Region read-after-write consistency applies the constraint for reads in the same region as a write. Global read-after-write consistency applies the constraint for all reads.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Eventual Consistency&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Eventual consistency requires that replicas “eventually” agree on a value of an object, i.e., when they all have received the same set of writes, they will have the same value.&lt;/li&gt;
&lt;li&gt;Eventual consistency allows replicas to answer reads immediately using their current version of the data, while writes are asynchronously propagated in the background. While writes are propagating between replicas, different replicas may return different results for reads.&lt;/li&gt;
&lt;li&gt;A client can update any replica of an object and all updates to an object will eventually be applied, but potentially in different orders at different replicas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Facebook’s Consistency&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;per-object sequential consistency (per-cache) + read-after-write (per-cache) + eventual consistency (across caches)&lt;/li&gt;
&lt;li&gt;User sessions are typically handled exclusively by one leaf cache, and thus we expect most of them to receive per-object sequential and read-after-write consistency.&lt;/li&gt;
&lt;li&gt;User sessions spread across multiple leaf caches receive eventual consistency.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;https://www.cs.utexas.edu/~vijay/cs380D-s18/feb6-fb.pdf&lt;/li&gt;
&lt;li&gt;https://www.allthingsdistributed.com/2008/12/eventually_consistent.html&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category></entry><entry><title>"PNUTS: Yahoo!’s Hosted Data Serving Platform"</title><link href="https://zhu45.org/posts/2018/Mar/08/pnuts-yahoos-hosted-data-serving-platform/" rel="alternate"></link><published>2018-03-08T20:24:00+08:00</published><updated>2018-03-08T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-08:/posts/2018/Mar/08/pnuts-yahoos-hosted-data-serving-platform/</id><summary type="html">&lt;p&gt;&amp;ldquo;PNUTS: Yahoo!’s Hosted Data Serving Platform&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#data-and-query-model"&gt;Data and Query Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#consistency-model"&gt;Consistency Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-architecture"&gt;System Architecture&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#data-storage-and-retrieval"&gt;Data Storage and Retrieval&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#replication-and-consistency"&gt;Replication and Consistency&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#ymb"&gt;YMB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#consistency-via-ymb-and-mastership"&gt;Consistency via YMB and mastership&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#recovery"&gt;Recovery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#other-database-system-functionality"&gt;Other Database System Functionality&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#query-processing"&gt;Query Processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#notifications"&gt;Notifications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#further-readings"&gt;Further Readings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;PNUTS system, a massive-scale, hosted database system to support Yahoo!’s web applications. 
Our focus is on data serving for web applications, rather than complex queries, e.g., offline analysis of web crawls.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PNUTS Goals&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Low latency, predictable latency&lt;/li&gt;
&lt;li&gt;Must handle attacks: flash crowds, denial of service&lt;/li&gt;
&lt;li&gt;High Availability &lt;/li&gt;
&lt;li&gt;Eventual Consistency&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Design Purpose&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our system is designed primarily for online serving workloads that consist mostly of queries that read and write single records or small groups of records&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Application scenarios&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;User database &lt;/li&gt;
&lt;li&gt;Social Applications &lt;/li&gt;
&lt;li&gt;Metadata for file systems &lt;/li&gt;
&lt;li&gt;Listings Management&lt;/li&gt;
&lt;li&gt;Session Data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PNUTS Overview&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data Model and Features&lt;ul&gt;
&lt;li&gt;a simple relational model to users, and supports single-table scans with predicates&lt;/li&gt;
&lt;li&gt;Features:&lt;ul&gt;
&lt;li&gt;catter-gather operations&lt;/li&gt;
&lt;li&gt;a facility for asynchronous notification of clients&lt;/li&gt;
&lt;li&gt;a facility for bulk loading.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fault Tolerance&lt;ul&gt;
&lt;li&gt;employs redundancy at multiple levels (data, metadata, serving components, etc.) and leverages our consistency model to support highly-available reads and writes even after a failure or partition&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pub-Sub Message System&lt;ul&gt;
&lt;li&gt;We chose pub/sub over other asynchronous protocols (such as gossip) because it can be optimized for 
geographically distant replicas and because replicas do not need to know the location of other replicas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Record-level Mastering&lt;ul&gt;
&lt;li&gt;To meet response-time goals, PNUTS cannot use write-all replication protocols that are employed by systems deployed in localized clusters (e.g. GFS)&lt;/li&gt;
&lt;li&gt;Not every read of the data necessarily needs to see the most current version. We have therefore chosen to make all high latency operations asynchronous, and to support record-level mastering.&lt;/li&gt;
&lt;li&gt;Asynchrony allows us to satisfy latency budget (50-100 ms) despite geographic distribution, while record-level mastering allows most requests, including writes, to be satisfied locally.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hosting&lt;ul&gt;
&lt;li&gt;PNUTS is a hosted, centrally-managed database service shared by multiple applications&lt;/li&gt;
&lt;li&gt;Significantly reduces application development time&lt;/li&gt;
&lt;li&gt;Consolidating multiple applications onto a single service allows us to amortize operations costs over multiple applications, and apply the same best practices to the data management of many different applications&lt;/li&gt;
&lt;li&gt;having a shared service allows us to keep resources (servers, disks, etc.) in reserve and quickly assign them to applications experiencing a sudden upsurge in popularity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="data-and-query-model"&gt;Data and Query Model&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Data is organized into tables of records with attributes&lt;/li&gt;
&lt;li&gt;Each row has a primary row&lt;/li&gt;
&lt;li&gt;Rows can have binary blobs&lt;/li&gt;
&lt;li&gt;The query language of PNUTS supports selection and projection from a single table&lt;ul&gt;
&lt;li&gt;single-table queries in fact provide very flexible access compared to distributed hash or ordered data stores, and present opportunities for future optimization by the system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Queries:&lt;ul&gt;
&lt;li&gt;Point access: A user may update her own record, resulting in point access&lt;/li&gt;
&lt;li&gt;Range access: Another user may scan a set of friends in order by name, resulting in range access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;does not enforce constraints&lt;/li&gt;
&lt;li&gt;does not support complex ad hoc queries (joins, group-by, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="consistency-model"&gt;Consistency Model&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;per-record timeline consistency:&lt;ul&gt;
&lt;li&gt;all replicas of a given record apply all updates to the record in the same order&lt;/li&gt;
&lt;li&gt;same as per-object sequential consistency&lt;/li&gt;
&lt;li&gt;implementation:&lt;ul&gt;
&lt;li&gt;One of the replicas is designated as the master, independently for each record, and all updates to that record are forwarded to the master.&lt;/li&gt;
&lt;li&gt;the replica receiving the majority of write requests for a particular record becomes the master for that record&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;API Calls&lt;ul&gt;
&lt;li&gt;Different levels of consistency guarantee&lt;/li&gt;
&lt;li&gt;Read-any: Returns a possibly stale version of the record&lt;/li&gt;
&lt;li&gt;Read-critical(required_version): Returns a version of the record that is strictly newer than, or the same as the &lt;span class="math"&gt;\(required\_version\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Read-latest: Returns the latest copy of the record that reflects all writes that have succeeded&lt;/li&gt;
&lt;li&gt;Write: This call gives the same ACID guarantees as a transaction with a single write operation in it 
(e.g. blind writes, e.g., a user updating his status on his profile)&lt;/li&gt;
&lt;li&gt;Test-and-set-write(required_version): This call performs the requested write to the record if and only if the present version of the record is the same as required_version&lt;ul&gt;
&lt;li&gt;The test-and-set write ensures that two such concurrent increment transactions are properly serialized&lt;/li&gt;
&lt;li&gt;allows us to implement single-row transactions without any locks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;can provide serializability on a per-record basis&lt;ul&gt;
&lt;li&gt;no guarantees as to consistency for multi-record transactions&lt;/li&gt;
&lt;li&gt;if an application reads or writes the same record multiple times in the same “transaction,” the application must use record versions to validate its own reads and writes to ensure serializability for the “transaction.”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-architecture"&gt;System Architecture&lt;/h2&gt;
&lt;p&gt;&lt;img alt="PNUTS architecture" class="img-responsive" src="/images/pnuts-architecture.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The system is divided into regions, where each region contains a full complement of system components and a complete copy of each table&lt;ul&gt;
&lt;li&gt;Regions are typically, but not necessarily, ge- ographically distributed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;our system does not have a traditional database log or archive data&lt;ul&gt;
&lt;li&gt;use of a pub/sub mechanism for both reliability and replication&lt;/li&gt;
&lt;li&gt;we rely on the guaranteed delivery pub/sub mechanism to act as our redo log, replaying updates that are lost before being applied to disk due to failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="data-storage-and-retrieval"&gt;Data Storage and Retrieval&lt;/h3&gt;
&lt;p&gt;How the components within a region provide data storage and retrieval.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Data tables are horizontally partitioned into groups of records called &lt;strong&gt;tablets&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tablets are scattered across many servers&lt;/li&gt;
&lt;li&gt;each tablet is stored on a single server within a region&lt;/li&gt;
&lt;li&gt;Each server has 100s-1000s of tablet &lt;/li&gt;
&lt;li&gt;Tablet size: 100s of MB or a few GBs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Three components in architecture are primarily responsible for managing and providing access to data tablets: the storage unit, the router, and the tablet controller.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Storage Unit: get(), scan(), set() &lt;/li&gt;
&lt;li&gt;Updates are committed by first writing them to the message broker&lt;/li&gt;
&lt;li&gt;Router: identifies which tablet and server contain data &lt;ul&gt;
&lt;li&gt;implemented using &lt;em&gt;interval mapping&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Ordered data: key range sharded into tablets&lt;/li&gt;
&lt;li&gt;Unordered data: do the same with hash(key) &lt;/li&gt;
&lt;li&gt;Mapping information stored in memory &lt;/li&gt;
&lt;li&gt;Contains only a cached copy of the interval mapping (True source of mapping info: tablet controller)
&lt;img alt="interval mapping" class="img-responsive" src="/images/interval-mapping.png"/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The tablet controller determines &lt;ul&gt;
&lt;li&gt;when it is time to move a tablet between storage units for load balancing or recovery &lt;/li&gt;
&lt;li&gt;when a large tablet must be split. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="replication-and-consistency"&gt;Replication and Consistency&lt;/h3&gt;
&lt;p&gt;We use the Yahoo! &lt;strong&gt;message broker&lt;/strong&gt;, a publish/subscribe system developed at Yahoo!, both as our replacement for a redo log and as our replication mechanism.&lt;/p&gt;
&lt;h4 id="ymb"&gt;YMB&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Received messages are logged and replicated &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data updates are considered “committed” when they have been published to YMB.&lt;/li&gt;
&lt;li&gt;At some point after being committed, the update will be asynchronously propagated to different regions and applied to their replicas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When update has been applied to all replicas, log is pruned&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;YMB servers are present in different regions&lt;/li&gt;
&lt;li&gt;Cross-region traffic is limited to YMB&lt;/li&gt;
&lt;li&gt;Messages are ordered within a YMB region&lt;/li&gt;
&lt;li&gt;Across regions, different ordering is possible &lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="consistency-via-ymb-and-mastership"&gt;Consistency via YMB and mastership&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Per-record timeline consistency is provided by designating one copy of a record as the master, and directing all updates to the master copy. &lt;/li&gt;
&lt;li&gt;In this record-level mastering mechanism, mastership is assigned on a record-by-record basis, and different records in the same table can be mastered in different clusters. &lt;/li&gt;
&lt;li&gt;Update considered “committed” once YMB acks it &lt;/li&gt;
&lt;li&gt;A committed update may not be visible to other replicas&lt;/li&gt;
&lt;li&gt;Master replica for a given record is stored inside that record&lt;/li&gt;
&lt;li&gt;In order to enforce primary key constraints, we must send inserts of records with the same primary key to the same storage unit;
this storage unit will arbitrate and decide which insert came first and reject the others. 
Thus, we have to designate one copy of each tablet as the &lt;strong&gt;tablet master&lt;/strong&gt;, and send all inserts into a given tablet to the tablet master&lt;/li&gt;
&lt;li&gt;Tablet master can be different from record master&lt;/li&gt;
&lt;li&gt;Tablet master serializes updates to record &lt;/li&gt;
&lt;li&gt;Record master is the “true” copy of the data &lt;ul&gt;
&lt;li&gt;Update is considered “committed” once record master gets it&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="recovery"&gt;Recovery&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;the tablet controller requests a copy from a particular remote replica (the “source tablet”)&lt;/li&gt;
&lt;li&gt;a “checkpoint message” is published to YMB, to ensure that any in-flight updates at the time the copy is initiated are applied to the source tablet&lt;/li&gt;
&lt;li&gt;the source tablet is copied to the destination region&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="other-database-system-functionality"&gt;Other Database System Functionality&lt;/h3&gt;
&lt;h4 id="query-processing"&gt;Query Processing&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Scatter-gather engine is used&lt;/li&gt;
&lt;li&gt;Server has the engine, not the client&lt;ul&gt;
&lt;li&gt;Done to reduce network connections to the server&lt;/li&gt;
&lt;li&gt;Allows optimization over the whole scatter-gather call&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Range queries are broken up&lt;/li&gt;
&lt;li&gt;Clients keep a continuation object to continue the range query&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="notifications"&gt;Notifications&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;User can subscribe to notifications&lt;/li&gt;
&lt;li&gt;Built on top of pub/sub architecture&lt;/li&gt;
&lt;li&gt;Accomplished by talking to the YMB&lt;/li&gt;
&lt;li&gt;Each tablet has a topic that user subscribe to&lt;/li&gt;
&lt;li&gt;Whenever tablet is updated or split, notifications can be sent out&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="further-readings"&gt;Further Readings&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://highscalability.com/blog/2009/8/8/yahoos-pnuts-database-too-hot-too-cold-or-just-right.html"&gt;Yahoo!’S PNUTS Database: Too Hot, Too Cold Or Just Right?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;https://www.cs.utexas.edu/~vijay/cs380D-s18/feb8-pnuts-voting.pdf&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category></entry><entry><title>Cache, Lease, Consistency, Invalidation</title><link href="https://zhu45.org/posts/2018/Mar/07/cache-lease-consistency-invalidation/" rel="alternate"></link><published>2018-03-07T20:24:00+08:00</published><updated>2018-03-07T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-07:/posts/2018/Mar/07/cache-lease-consistency-invalidation/</id><summary type="html">&lt;p&gt;Cache, Lease, Consistency, Invalidation&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#concepts"&gt;Concepts&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#cache"&gt;Cache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#consistency-model"&gt;Consistency model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="concepts"&gt;Concepts&lt;/h2&gt;
&lt;h3 id="cache"&gt;Cache&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cache is built on client side&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write-through:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writes go to the server &lt;/li&gt;
&lt;li&gt;No modified caches&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write-back:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Writes go to cache&lt;/li&gt;
&lt;li&gt;Dirty cache written to server when necessary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Invalidations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Track where data is cached&lt;/li&gt;
&lt;li&gt;When doing a write, invalidate all (other) locations&lt;/li&gt;
&lt;li&gt;Data can live in multiple caches for reading&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write-through invalidations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Track all reading caches &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On a write: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server send invalidations to all caches &lt;/li&gt;
&lt;li&gt;Each cache invalidates, responds &lt;/li&gt;
&lt;li&gt;Server waits for all invalidations, do update&lt;/li&gt;
&lt;li&gt;Server return&lt;ul&gt;
&lt;li&gt;Reads can proceed:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If there is a cached copy and if no write waiting at server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write-back invalidations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Track all reading and writing caches&lt;/li&gt;
&lt;li&gt;On a write:&lt;ul&gt;
&lt;li&gt;Server send invalidations to all caches&lt;/li&gt;
&lt;li&gt;Each cache invalidates, responds (possibly with updated data)&lt;/li&gt;
&lt;li&gt;Wait for all invalidations&lt;/li&gt;
&lt;li&gt;Return&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reads can proceed when there is a local copy&lt;/li&gt;
&lt;li&gt;Order requests carefully at server &lt;ul&gt;
&lt;li&gt;Enforce processor order, avoid deadlock&lt;/li&gt;
&lt;li&gt;Write-through invalidation不用在server order requests因为所有writes直接在server端写，根据request来的order写就可以了。
但是Write-back invalidation需要在server端order因为写写在cache里，那么requests写的order就没有了，因此在cache把更新好的data
return给server端时，需要在server端重新排序。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Leases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Permission to serve data for some time period&lt;/li&gt;
&lt;li&gt;Wait until lease expires before applying updates&lt;/li&gt;
&lt;li&gt;Must account for clock skew!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strong Leases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The term “Lease” referred in Jim Gray’s paper&lt;/li&gt;
&lt;li&gt;Read request: key, TIL (time to live)&lt;ul&gt;
&lt;li&gt;When server returns, he server won’t accept writes to the key for TIL seconds after reply sent&lt;/li&gt;
&lt;li&gt;Client invalidates its cache after TTL seconds from when request was sent&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write-through strong leases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server queues writes until all leases expire (after all leases expire, the cache got invalidated and server then can write)&lt;/li&gt;
&lt;li&gt;Avoid starvation: don’t accept new reads&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write-back strong leases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cache can get a write lease (exclusive) &lt;/li&gt;
&lt;li&gt;Server queues read requests until lease expires&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strong leases vs. Invalidations&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strong leases potentially slower&lt;/li&gt;
&lt;li&gt;What if a cache fails when it has a key? Strong leases provide better availability &lt;/li&gt;
&lt;li&gt;Can combine techniques:&lt;ul&gt;
&lt;li&gt;Short lease on entire cache, periodically revalidated &lt;/li&gt;
&lt;li&gt;All keys invalidated on failure (after lease)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Weak leases&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cache values until lease expires&lt;/li&gt;
&lt;li&gt;Allow writes, other reads simultaneously&lt;/li&gt;
&lt;li&gt;Advantages:&lt;ul&gt;
&lt;li&gt;Stateless at server (don’t care who is caching) &lt;/li&gt;
&lt;li&gt;Reads, writes always processed immediately&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disadvantages:&lt;ul&gt;
&lt;li&gt;Consistency model&lt;/li&gt;
&lt;li&gt;Overhead of revalidations&lt;/li&gt;
&lt;li&gt;Synchronized revalidations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The key idea is that cache can become stale and we need to have a policy
for validating the a cached data item before using it. Thus, we have invalidations
and leases to answer the question: If we cache data, how do we make sure it reflects
writes of other nodes while maintaining performance? This question implies how we implement
consistency. For example, to ensure sequential consistency, we need to make sure all operations 
to a single key are serialized (as if all the operations go to a single copy), which is done
with the help of invalidations / leases.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="consistency-model"&gt;Consistency model&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Anomaly&lt;/strong&gt;: some sequence of operations (reads and writes) that “shouldn’t” be allowed &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Consistency model:  which anomalies are possible&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Linearizability (Strict Consistency, Strong Consistency)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;matches the ideal system&lt;/li&gt;
&lt;li&gt;Talks about single operations on single objects&lt;/li&gt;
&lt;li&gt;Literally means: “did the operations happen in a straight line (one after the other)?” &lt;/li&gt;
&lt;li&gt;Reads always reflect latest write (i.e. Once a read returns value V1, all reads have to return V1 or later values)&lt;/li&gt;
&lt;li&gt;Concurrent operations can be executed in any order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Serializability (Sequential Consistency)&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Execution always equivalent to some interleaving&lt;/li&gt;
&lt;li&gt;Each node’s operations done in order &lt;/li&gt;
&lt;li&gt;Guarantees execution of a set of operations (usually each a transaction) is equivalent to some serial execution order &lt;/li&gt;
&lt;li&gt;Given operations A1, and A2 serializability only demands that the execution order is A1 followed by A2 or A2 followed by A1 &lt;/li&gt;
&lt;li&gt;Serializability makes it seem as if there are no concurrent operations, everything happened one after another&lt;/li&gt;
&lt;li&gt;Relaxation of linearizability &lt;/li&gt;
&lt;li&gt;Instead of conforming to a real-time partial order, we use a client-observed partial order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;“The result of any execution is the same as if the operations of all the processes were executed in some sequential order and the operations of each individual process appear in this sequence in the order specified by its program” (Lamport, 1979)
There is a order on all the processes and operations in each process are ordered in the way sent out by its program.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Strict Serializability&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Combines linearizability and serializability&lt;/li&gt;
&lt;li&gt;Transactions need to happen in real-time order&lt;/li&gt;
&lt;li&gt;T1 and T2 are executing concurrently &lt;ul&gt;
&lt;li&gt;T1 writes object A, and later T2 reads object A&lt;/li&gt;
&lt;li&gt;Strict Serializability: T1 before T2 &lt;/li&gt;
&lt;li&gt;Serializability: T2 before T1 also valid (In this case, T2 will read old value of object A)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Weaker models (could have anomalies):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Read Your Writes + Eventual Consistency (anomalies are “temporary”)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Facebook model, approximately &lt;/li&gt;
&lt;li&gt;Clients will always see their own writes &lt;/li&gt;
&lt;li&gt;Clients will eventually see everyone’s writes &lt;/li&gt;
&lt;li&gt;Eventually the order will be consistent&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Causal consistency &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Causal order (Lamport happens-before) observed everywhere &lt;/li&gt;
&lt;li&gt;Concurrent events can have arbitrary and inconsistent order &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transactional models (e.g. Snapshot reads)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some other consistency model + atomicity of transactions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Another angle to look at consistency model is: a contract between the data store and its clients that
specifies the results that clients can expect to obtain when accessing the data store.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Why different models?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Tradeoff between:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Performance: consistency requires sync &lt;/li&gt;
&lt;li&gt;Availability: want to operate when disconnected &lt;/li&gt;
&lt;li&gt;Programmability: weaker consistency makes applications harder to write (i.e., harder to provide app-level guarantees) &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you want availability, must give up consistency (by CAP (Consistency, availability, partition tolerance))&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;https://courses.cs.washington.edu/courses/cse452/17sp/slides/Caching.pdf (Examples on different consistency models)&lt;/li&gt;
&lt;li&gt;https://courses.cs.washington.edu/courses/cse452/17sp/slides/ImplementingCaches1&lt;/li&gt;
&lt;li&gt;https://www.cs.utexas.edu/~vijay/cs380D-s18/feb6-fb.pdf&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.utexas.edu/users/ans/classes/cs439/schedule.html"&gt;CS439 Alison’s slide “Other File Systems”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="distributed systems"></category><category term="system concepts"></category></entry><entry><title>State Machine Replication Approach</title><link href="https://zhu45.org/posts/2018/Mar/07/state-machine-replication-approach/" rel="alternate"></link><published>2018-03-07T20:24:00+08:00</published><updated>2018-03-07T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-07:/posts/2018/Mar/07/state-machine-replication-approach/</id><summary type="html">&lt;p&gt;State Machine Replication Approach&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#state-machine-replication"&gt;State Machine Replication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#applications"&gt;Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="state-machine-replication"&gt;State Machine Replication&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;State Machine Replaction system properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zhu45.org/posts/2018/Jan/21/why-do-computers-stop-and-what-can-be-done-about-it/"&gt;Available&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Fault tolerant&lt;/li&gt;
&lt;li&gt;Appear to behave like a single machine&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;t fault tolerant: A system consisting of a set of distinct components is &lt;em&gt;t fault tolerant&lt;/em&gt;
if it satisfies its specification provided that no more than &lt;em&gt;t&lt;/em&gt; of those components become 
faulty during some interval of interest.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;t fault-tolerant state machine implementation:  replicating that state machine and running
a replica on each of the processors in a distributed system. Provided each replica being run
by a nonfaulty processor starts in the same initial state and executes the same requests in 
the same order, then each will do the same thing and produce the same output.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When processors can experience Byzantine failures, an ensemble implementing a 
t fault-tolerant state machine must have at least &lt;span class="math"&gt;\(2t + 1\)&lt;/span&gt; replicas, 
and the output of the ensemble is the output produced by the majority of the replicas. 
(因为Byzantine failures可以产生错误的结果，因此需要大多数replica的结果正确。由于我们是t fault-tolerant,
因此有t replicas可以产生Byzantine failures，因此我们需要额外t+1产生正确结果的replica,也就是2t+1 total replicas)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If processors experience only fail-stop failures, then an ensemble containing &lt;span class="math"&gt;\(t + 1\)&lt;/span&gt; replicas suffices, 
and the output of the ensemble can be the output produced by any of its members.
(Fail-stop failures的话，replica产生错误就停止工作了，因此我们总共只需要t+1 replicas因为只要保证有一个replica工作就可以了)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implementing Replication:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Agreement: Every nonfaulty state machine replica receives every request.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implemented by clients&lt;/li&gt;
&lt;li&gt;When a client makes a request, it broadcasts the request to all servers in the system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Order: Every nonfaulty state machine replica processes the requests it receives in the same relative order.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implemented by servers&lt;/li&gt;
&lt;li&gt;Define a total order of requests in the system and execute requests in that order&lt;/li&gt;
&lt;li&gt;Process a request with the lowest timestamp that has been received by that replica&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Stability&lt;/strong&gt;: The replica can never receive an event with a lower timestamp&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implementing stability: Receive requests from a client in increasing order (Given by FIFO channels and logical clocks)&lt;/li&gt;
&lt;li&gt;A request is stable once a request has been received from each client with a greater timestamp&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="applications"&gt;Applications&lt;/h2&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="distributed systems"></category><category term="system concepts"></category><category term="system design principle"></category></entry><entry><title>Lamport Clocks, Vector Clocks</title><link href="https://zhu45.org/posts/2018/Mar/06/lamport-clocks-vector-clocks/" rel="alternate"></link><published>2018-03-06T20:24:00+08:00</published><updated>2018-03-06T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-06:/posts/2018/Mar/06/lamport-clocks-vector-clocks/</id><summary type="html">&lt;p&gt;Lamport Clocks, Vector Clocks&lt;/p&gt;</summary><content type="html">&lt;h2 id="lamport-clocks"&gt;Lamport Clocks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In a distributed system, there is &lt;strong&gt;no global time&lt;/strong&gt; and &lt;strong&gt;no global state&lt;/strong&gt; &lt;span class="math"&gt;\(\implies\)&lt;/span&gt; the clock of different nodes in a distributed system
can have different values.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Happened-before Relationship:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some events in a distributed system happened before other events and others are concurrent&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Happened-before is a partial ordering on events in a distributed system:&lt;/p&gt;
&lt;p&gt;Given events &lt;span class="math"&gt;\(E1, E2, E3\)&lt;/span&gt; and &lt;span class="math"&gt;\(E1\)&lt;/span&gt; happens before &lt;span class="math"&gt;\(E2\)&lt;/span&gt; and &lt;span class="math"&gt;\(E1\)&lt;/span&gt; happens before &lt;span class="math"&gt;\(E3\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(E2\)&lt;/span&gt; and &lt;span class="math"&gt;\(E3\)&lt;/span&gt; are concurrent and
&lt;span class="math"&gt;\(E1 &amp;lt; E3\)&lt;/span&gt; and &lt;span class="math"&gt;\(E1 &amp;lt; E3\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\rightarrow\)&lt;/span&gt; relation satisfies the following conditions:&lt;/p&gt;
&lt;p&gt;1) If &lt;span class="math"&gt;\(a\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt; are events in the same process, and &lt;span class="math"&gt;\(a\)&lt;/span&gt; comes before &lt;span class="math"&gt;\(b\)&lt;/span&gt;, then &lt;span class="math"&gt;\(a \rightarrow b\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;2) If &lt;span class="math"&gt;\(a\)&lt;/span&gt; is the sending of a message by one process and &lt;span class="math"&gt;\(b\)&lt;/span&gt; is the receipt of the same message by another process, then &lt;span class="math"&gt;\(a \rightarrow b\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;3) If &lt;span class="math"&gt;\(a \rightarrow b\)&lt;/span&gt; and &lt;span class="math"&gt;\(b \rightarrow c\)&lt;/span&gt;, then &lt;span class="math"&gt;\(a \rightarrow c\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two distinct events &lt;span class="math"&gt;\(a\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt; are said to be concurrent if &lt;span class="math"&gt;\(a \not\rightarrow b\)&lt;/span&gt; and &lt;span class="math"&gt;\(b \not\rightarrow a\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Logical Clocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assigns a monotonically increasing number &lt;span class="math"&gt;\(C(x)\)&lt;/span&gt; for each event &lt;span class="math"&gt;\(x\)&lt;/span&gt; in a process &lt;/li&gt;
&lt;li&gt;If event &lt;span class="math"&gt;\(x\)&lt;/span&gt; happens before event &lt;span class="math"&gt;\(y\)&lt;/span&gt;, &lt;span class="math"&gt;\(C(x) &amp;lt; C(y)\)&lt;/span&gt; (Note, &lt;span class="math"&gt;\(C(x) &amp;lt; C(y) \not\implies x &amp;lt; y\)&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(x\)&lt;/span&gt; and &lt;span class="math"&gt;\(y\)&lt;/span&gt; are in the same process, and &lt;span class="math"&gt;\(x &amp;lt; y\)&lt;/span&gt;, then &lt;span class="math"&gt;\(C(x) &amp;lt; C(y)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(x\)&lt;/span&gt; is sending of message, and &lt;span class="math"&gt;\(y\)&lt;/span&gt; receipt of the message, then &lt;span class="math"&gt;\(x &amp;lt; y\)&lt;/span&gt; and &lt;span class="math"&gt;\(C(x) &amp;lt; C(y)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implementing Logical Clocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Within a process &lt;span class="math"&gt;\(X\)&lt;/span&gt;, increment &lt;span class="math"&gt;\(C(x)\)&lt;/span&gt; every time an event happens&lt;/li&gt;
&lt;li&gt;When process &lt;span class="math"&gt;\(X\)&lt;/span&gt; receives a message with timestamp &lt;span class="math"&gt;\(T\)&lt;/span&gt;, &lt;span class="math"&gt;\(C(x) = \max(T, C(x)) + 1\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;How do we break the tie of the concurrent events and achive total ordering of the events in the sytem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(x\)&lt;/span&gt; and &lt;span class="math"&gt;\(y\)&lt;/span&gt; in same process, and &lt;span class="math"&gt;\(x &amp;lt; y\)&lt;/span&gt;, &lt;span class="math"&gt;\(C(x) &amp;lt; C(y)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(x\)&lt;/span&gt; and &lt;span class="math"&gt;\(y\)&lt;/span&gt; are concurrent (&lt;span class="math"&gt;\(x = y\)&lt;/span&gt;), then &lt;span class="math"&gt;\(P(x) &amp;lt; P(y) \implies C(x) &amp;lt; C(y)\)&lt;/span&gt; (&lt;span class="math"&gt;\(P(\cdot)\)&lt;/span&gt; means process ID)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vector-clocks"&gt;Vector Clocks&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Limitation of Lamport Clocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(C(x) &amp;lt; C(y)\)&lt;/span&gt;, we cannot tell whether &lt;span class="math"&gt;\(x &amp;lt; y\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;We can only say if &lt;span class="math"&gt;\(x &amp;lt; y\)&lt;/span&gt;, then &lt;span class="math"&gt;\(C(x) &amp;lt; C(y)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Goal: to enable each process to have an &lt;strong&gt;approximation of global time&lt;/strong&gt; at all processes (Every message propagates info
about state of whole system)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each process has a vector of clocks: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clock &lt;span class="math"&gt;\(C_i\)&lt;/span&gt; is time for process &lt;span class="math"&gt;\(i\)&lt;/span&gt; as seen by the owner of the vector &lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(C_i\)&lt;/span&gt; in two different vectors may not be the same&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implementing Vector Clocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each process &lt;span class="math"&gt;\(P_i\)&lt;/span&gt; updates its component &lt;span class="math"&gt;\(C_i\)&lt;/span&gt; in its vector clock (This update happens for each internal event (e.g. on receiving a message))&lt;/li&gt;
&lt;li&gt;Each message has a vector clock time stamp&lt;/li&gt;
&lt;li&gt;On getting the message, for each field &lt;span class="math"&gt;\(x\)&lt;/span&gt; in the vector: &lt;span class="math"&gt;\(C[x] = \max(C[x], message\_time\_stamp[x])\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Comparing Vector Timestamps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timestamp &lt;span class="math"&gt;\(X \le Y\)&lt;/span&gt; if all components of &lt;span class="math"&gt;\(X \le\)&lt;/span&gt; corresponding components in &lt;span class="math"&gt;\(Y\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Timestamp &lt;span class="math"&gt;\(X &amp;lt; Y\)&lt;/span&gt; if at least one component is strictly lesser, with all others being equal  &lt;/li&gt;
&lt;li&gt;Otherwise, &lt;span class="math"&gt;\(X\)&lt;/span&gt; and &lt;span class="math"&gt;\(Y\)&lt;/span&gt; are concurrent&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="distributed systems"></category><category term="system concepts"></category></entry><entry><title>Distributed System Reference Guide</title><link href="https://zhu45.org/posts/2018/Mar/06/distributed-system-reference-guide/" rel="alternate"></link><published>2018-03-06T16:24:00+08:00</published><updated>2018-03-06T16:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-03-06:/posts/2018/Mar/06/distributed-system-reference-guide/</id><summary type="html"></summary><content type="html">&lt;p&gt;This post is reference guide that points to the concepts, system design principles, system concepts
mentioned in my posts.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#system-concepts"&gt;System Concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#protocol"&gt;Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-designs"&gt;System Designs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#system-principles"&gt;System Principles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="system-concepts"&gt;System Concepts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zhu45.org/posts/2018/Mar/06/lamport-clocks-vector-clocks/"&gt;Logical Clocks, Vector Clocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;State Machine&lt;/strong&gt;: A process whose state depends entirely on the starting state and sequence of operations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Replication&lt;/strong&gt;: All servers exhibit the same behavior&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sharding&lt;/strong&gt;: Different data on different servers; Partitioned via some function on keys &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clock Skew&lt;/strong&gt;: the same sourced clock signal arrives at different components at different times&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="protocol"&gt;Protocol&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zhu45.org/posts/2018/Mar/08/pnuts-yahoos-hosted-data-serving-platform/"&gt;Pub/Sub Mechanism from PNUTS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-designs"&gt;System Designs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zhu45.org/posts/2018/Mar/07/state-machine-replication-approach/"&gt;State Machine Replication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="system-principles"&gt;System Principles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Scability: sharding + replication&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usually, shard then replicate &lt;/li&gt;
&lt;li&gt;Each piece of data lives on one replicated shard&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stronger consistency models are easier to reason about (and program for), but more expensive to obtain &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Weaker consistency models provide more performance, but hard to understand and program for&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category><category term="protocol"></category><category term="system design principle"></category><category term="system concepts"></category></entry><entry><title>"Why do computers stop and what can be done about it?"</title><link href="https://zhu45.org/posts/2018/Jan/21/why-do-computers-stop-and-what-can-be-done-about-it/" rel="alternate"></link><published>2018-01-21T20:24:00+08:00</published><updated>2018-01-21T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-01-21:/posts/2018/Jan/21/why-do-computers-stop-and-what-can-be-done-about-it/</id><summary type="html">&lt;p&gt;&amp;ldquo;Why do computers stop and what can be done about it?&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#availability"&gt;Availability&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#terminology"&gt;Terminology&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#key-to-availability"&gt;Key to Availability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#achieving-high-availability"&gt;Achieving High Availability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#study-of-failures"&gt;Study of Failures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lessons-from-tandem-study"&gt;Lessons from Tandem Study&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#software-fault-tolerance"&gt;Software Fault Tolerance&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#containing-software-faults"&gt;Containing Software Faults&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fail-fast-software"&gt;Fail Fast Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#process-pairs"&gt;Process Pairs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#transactions"&gt;Transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fault-tolerant-communication"&gt;Fault-Tolerant Communication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Gray, J. &lt;a href="http://pages.cs.wisc.edu/~remzi/Classes/739/Fall2017/Papers/gray-why-do-computers-stop-85.pdf"&gt;Why do computers stop and what can be done about it?&lt;/a&gt;, 1985.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="availability"&gt;Availability&lt;/h2&gt;
&lt;h3 id="terminology"&gt;Terminology&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mean Time Between Failures (MTBF)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mean Time to Repair (MTTR)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Availability&lt;/strong&gt;: percentage of time the system is operational&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(99.37\%\)&lt;/span&gt; percentage availability over 10 days translates to 1.5 hours outage every 10 days on average (i.e. &lt;span class="math"&gt;\((1 - 99.37\%) \times 10 \times 24 = 1.51\)&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;Availability = MTBF / (MTBF + MTTR) = &lt;span class="math"&gt;\(\frac{10*24}{(10*24 + 1.5)} = 0.9937\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(90\%\)&lt;/span&gt; of servers are available &lt;span class="math"&gt;\(90\%\)&lt;/span&gt; of the time, overall availability could be &lt;span class="math"&gt;\(81\%\)&lt;/span&gt; (could be higher when using certain techniques)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="key-to-availability"&gt;Key to Availability&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If MTTR is zero, then Availability = MTTF/ (MTTF + 0) = 1&lt;/li&gt;
&lt;li&gt;We need to give the illusion of instantaneous repair&lt;/li&gt;
&lt;li&gt;Key idea: Modularize the system so that modules can be repaired “instantly”&lt;/li&gt;
&lt;li&gt;How to provide instant repair? Have a “hot” spare that can take over instantly&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We can analyze schemes to increase availability along several dimensions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CAPEX (one time capital expense) &lt;/li&gt;
&lt;li&gt;OPEX (on-going operating expenses) &lt;/li&gt;
&lt;li&gt;Increase in latency?&lt;/li&gt;
&lt;li&gt;Reduction in throughput?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="achieving-high-availability"&gt;Achieving High Availability&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Key ideas: &lt;strong&gt;modularity&lt;/strong&gt; and &lt;strong&gt;redundancy&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modularity: a failure within a module affects only that module&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;von Neuman’s system required 20K replicas to achieve a MTBF of 100 years&lt;/li&gt;
&lt;li&gt;Why? No modularity&lt;/li&gt;
&lt;li&gt;Large combinations of modules were replicated&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jim Gray’s algorithm (can have the system has MTBF in decades or centuries)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hierarchically decompose the system into modules&lt;/li&gt;
&lt;li&gt;Design each module to have MTBF &amp;gt; 1 year&lt;/li&gt;
&lt;li&gt;Make each module fail-fast&lt;/li&gt;
&lt;li&gt;Have a heart-beat message for each module so you know when it fails&lt;/li&gt;
&lt;li&gt;Have spare modules which pick up job of failed module. Failover to spare module should be quick.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="study-of-failures"&gt;Study of Failures&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Analyzed cause of failures over 7 months &lt;/li&gt;
&lt;li&gt;Study covers 2000 systems, 10M system hours &lt;/li&gt;
&lt;li&gt;166 failures reported in this period&lt;/li&gt;
&lt;li&gt;59 of these failures are “infant” failures - faulty hardware or new &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;42% of failures caused by system administration&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Includes software and hardware maintenance: 25% &lt;/li&gt;
&lt;li&gt;Operations: 9%, configuration: 8%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;25% software failures, 18% hardware failures&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;14% of failures caused by environmental failures &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;9% power failures, 5% communication and facilities&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lessons-from-tandem-study"&gt;Lessons from Tandem Study&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Key to high availability: tolerating human errors and operations failures&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Need to design systems to have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal configuration &lt;/li&gt;
&lt;li&gt;Minimal maintenance &lt;/li&gt;
&lt;li&gt;Simple, consistent interfaces&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;New systems often have higher failure rate&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need time to work out these bugs&lt;/li&gt;
&lt;li&gt;Do not deploy systems until they become stable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jim Gray suggests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do regular hardware maintenance&lt;/li&gt;
&lt;li&gt;Delay software upgrades as long as possible, allow them time to become mature&lt;/li&gt;
&lt;li&gt;Only patch a bug if it is causing outages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="software-fault-tolerance"&gt;Software Fault Tolerance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Applying lessons from before:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Software modularity through processes and messages &lt;/li&gt;
&lt;li&gt;Fail-fast software modules&lt;/li&gt;
&lt;li&gt;Process-pairs to handle transient faults&lt;/li&gt;
&lt;li&gt;Transactions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Underlying assumption: software faults are transient&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why? The hard software faults would have been removed in testing and quality assurance checks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="containing-software-faults"&gt;Containing Software Faults&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two main approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Static checking checks the code before it is even run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conservative checking&lt;/li&gt;
&lt;li&gt;May throw up lots of false positives&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dynamic checking checks code that is executed&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Has lower false positives&lt;/li&gt;
&lt;li&gt;Might not catch all bugs, especially in rarely run code paths&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fail-fast-software"&gt;Fail Fast Software&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In today’s terms, lots of assert conditions in the code&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux kernel is filled with PANIC calls. If something goes wrong, print the stack trace and kill the kernel.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="process-pairs"&gt;Process Pairs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When one process fails, the other process takes over&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Types of process pairs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lockstep: both execute every instruction&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Checkpointing: primary occasionally checkpoints its state, which is copied over to backup&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Variants: Delta Checkpointing, Kernel Checkpointing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Persistence: backup gets all its knowledge from persistent storage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Need to ensure persistent storage is not inconsistent&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="transactions"&gt;Transactions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Provide the ACID property: atomicity, consistency, isolation, durability&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Jim Gray argues for persistent process pairs combined with transactions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implemented in the Encompass system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fault-tolerant-communication"&gt;Fault-Tolerant Communication&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Key idea: sessions and sequence numbers &lt;/li&gt;
&lt;li&gt;Same idea used in TCP&lt;/li&gt;
&lt;li&gt;Sequence numbers used to identify duplicate and lost messages&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category><category term="system design principle"></category><category term="system concepts"></category></entry><entry><title>"Introduction to Distributed System Design"</title><link href="https://zhu45.org/posts/2018/Jan/17/introduction-to-distributed-system-design/" rel="alternate"></link><published>2018-01-17T16:24:00+08:00</published><updated>2018-01-17T16:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-01-17:/posts/2018/Jan/17/introduction-to-distributed-system-design/</id><summary type="html">&lt;p&gt;&amp;ldquo;Introduction to Distributed System Design&amp;rdquo; paper reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#the-basics"&gt;The Basics&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#what-is-a-distributed-system"&gt;What is a distributed system?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#why-build-a-distributed-system"&gt;Why build a distributed system?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#how-can-a-distributed-system-be-reliable"&gt;How can a distributed system be reliable?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#category-of-failures-in-a-distributed-system"&gt;Category of failures in a distributed system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#so-how-is-it-done"&gt;So How Is It Done?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#remote-procedure-calls"&gt;Remote Procedure Calls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#distributed-design-principles"&gt;Distributed Design Principles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;O. Tatebe, &lt;a href="http://www.hpcs.cs.tsukuba.ac.jp/~tatebe/lecture/h23/dsys/dsd-tutorial.html"&gt;“Introduction to Distributed System Design”&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="the-basics"&gt;The Basics&lt;/h2&gt;
&lt;h3 id="what-is-a-distributed-system"&gt;What is a distributed system?&lt;/h3&gt;
&lt;p&gt;Here is a “cascading” definition of a distributed system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;program&lt;/strong&gt;: is the code you write.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;process&lt;/strong&gt;: is what you get when you run it.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;message&lt;/strong&gt;: is used to communicate between processes.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;packet&lt;/strong&gt;: is a fragment of a message that might travel on a wire.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;protocol&lt;/strong&gt;: is a formal description of message formats and the rules that two processes must follow in order to exchange those messages.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;network&lt;/strong&gt;: is the infrastructure that links computers, workstations, terminals, servers, etc. It consists of routers which are connected by communication links.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;component&lt;/strong&gt;: can be a process or any piece of hardware required to run a process, support communications between processes, store data, etc.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;distributed system&lt;/strong&gt;:  is an application that executes a collection of protocols to coordinate the actions of multiple processes on a network, such that all components cooperate together to perform a single or small set of related tasks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="why-build-a-distributed-system"&gt;Why build a distributed system?&lt;/h3&gt;
&lt;p&gt;There are lots of advantages including the ability to connect remote users with remote resources in an &lt;em&gt;open&lt;/em&gt; and &lt;em&gt;scalable&lt;/em&gt; way. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;open&lt;/em&gt;: each component is continually open to interaction with other components. &lt;/li&gt;
&lt;li&gt;&lt;em&gt;scalable&lt;/em&gt;: the system can easily be altered to accommodate changes in the number of users, resources and computing entities.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="how-can-a-distributed-system-be-reliable"&gt;How can a distributed system be reliable?&lt;/h3&gt;
&lt;p&gt;For a distributed system to be useful, it must be reliable. To be truly reliable, a distributed system must have the following characteristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fault-Tolerant&lt;/strong&gt;: It can recover from component failures without performing incorrect actions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Highly Available&lt;/strong&gt;: It can restore operations, permitting it to resume providing services even when some components have failed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recoverable&lt;/strong&gt;: Failed components can restart themselves and rejoin the system, after the cause of failure has been repaired.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistent&lt;/strong&gt;: The system can coordinate actions by multiple components often in the presence of concurrency and failure. This underlies the ability of a distributed system to act like a non-distributed system.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scalable&lt;/strong&gt;: It can operate correctly even as some aspect of the system is scaled to a larger size. For example, we might increase the size of the network on which the system is running. This increases the frequency of network outages and could degrade a “non-scalable” system. Similarly, we might increase the number of users or servers, or overall load on the system. In a scalable system, this should not have a significant effect.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Predictable Performance&lt;/strong&gt;: The ability to provide desired responsiveness in a timely manner.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secure&lt;/strong&gt;: The system authenticates access to data and services.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="category-of-failures-in-a-distributed-system"&gt;Category of failures in a distributed system&lt;/h3&gt;
&lt;p&gt;When you design distributed systems, you have to say, “Failure happens all the time.” So when you design, you design for failure. It is your number one concern. 
Failures fall into two obvious categories: hardware and software.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hardware failures: today, problems are most often associated with connections and mechanical devices, i.e., network failures and drive failures.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Software failures: residual bugs in mature systems can be classified into two main categories&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Heisenbug&lt;/strong&gt;: A bug that seems to disappear or alter its characteristics when it is observed or researched. A common example is a bug that occurs in a release-mode compile of a program, but not when researched under debug-mode.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bohrbug&lt;/strong&gt;: A bug (named after the Bohr atom model) that, in contrast to a heisenbug, does not disappear or alter its characteristics when it is researched. A Bohrbug typically manifests itself reliably under a well-defined set of conditions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Heisenbugs tend to be more prevalent in distributed systems than in local systems. 
One reason for this is the difficulty programmers have in obtaining a coherent and comprehensive view of the interactions of concurrent processes.&lt;/p&gt;
&lt;p&gt;The types of failures that can occur in a distributed system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Halting failures&lt;/strong&gt;: A component simply stops. There is no way to detect the failure except by timeout: it either stops sending “I’m alive” (heartbeat) messages or fails to respond to requests. Your computer freezing is a halting failure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fail-stop&lt;/strong&gt;: A halting failure with some kind of notification to other components. A network file server telling its clients it is about to go down is a fail-stop.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Omission failures&lt;/strong&gt;: Failure to send/receive messages primarily due to lack of buffering space, which causes a message to be discarded with no notification to either the sender or receiver. This can happen when routers become overloaded.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network failures&lt;/strong&gt;: A network link breaks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network partition failure&lt;/strong&gt;: A network fragments into two or more disjoint sub-networks within which messages can be sent, but between which messages are lost. This can occur due to a network failure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timing failures&lt;/strong&gt;: A temporal property of the system is violated. For example, clocks on different computers which are used to coordinate processes are not synchronized; when a message is delayed longer than a threshold period, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Byzantine failures&lt;/strong&gt;: This captures several types of faulty behaviors including data corruption or loss, failures caused by malicious programs, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To design for failure, we must be careful to not make any assumptions about the reliability of the components of a system. Everyone, when they first build a 
distributed system, makes the following eight assumptions, which are referred as “8 Fallacies”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The network is reliable.&lt;/li&gt;
&lt;li&gt;Latency is zero.&lt;/li&gt;
&lt;li&gt;Bandwidth is infinite.&lt;/li&gt;
&lt;li&gt;The network is secure.&lt;/li&gt;
&lt;li&gt;Topology doesn’t change.&lt;/li&gt;
&lt;li&gt;There is one administrator.&lt;/li&gt;
&lt;li&gt;Transport cost is zero.&lt;/li&gt;
&lt;li&gt;The network is homogeneous. &lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Latency&lt;/strong&gt;: the time between initiating a request for data and the beginning of the actual data transfer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bandwidth&lt;/strong&gt;: A measure of the capacity of a communications channel. The higher a channel’s bandwidth, the more information it can carry.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Topology&lt;/strong&gt;: The different configurations that can be adopted in building networks, such as a ring, bus, star or meshed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Homogeneous network&lt;/strong&gt;: A network running a single network protocol.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="so-how-is-it-done"&gt;So How Is It Done?&lt;/h2&gt;
&lt;p&gt;We will focus on a particular type of distributed systems design, one that uses a client-server model with mostly standard protocols. It turns out that these standard protocols provide considerable help with the low-level details of reliable network communications, which makes our job easier. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In client-server applications, the &lt;strong&gt;server&lt;/strong&gt; provides some service, such as processing database queries or sending out current stock prices.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;client&lt;/strong&gt; uses the service provided by the server, either displaying database query results to the user or making stock purchase recommendations to an investor. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="client-server" class="img-responsive" src="/images/client-server.gif"/&gt;&lt;/p&gt;
&lt;p&gt;The communication that occurs between the client and the server must be reliable. That is, no data can be dropped and 
it must arrive on the client side in the same order in which the server sent it. Types of server are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;File servers&lt;/em&gt; manage disk storage units on which file systems reside. &lt;/li&gt;
&lt;li&gt;&lt;em&gt;Database servers&lt;/em&gt; house databases and make them available to clients.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Network name servers&lt;/em&gt; implement a mapping between a symbolic name or a service description and a value such as an IP address and port number for a process that provides the service.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some key terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Service&lt;/strong&gt; is used to denote a set of servers of a particular type.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;strong&gt;binding&lt;/strong&gt; occurs when a process that needs to access a service becomes associated with a particular server which provides the service.&lt;/p&gt;
&lt;p&gt;There are many binding policies that define how a particular server is chosen. For example, the policy could be based on locality (a Unix NIS client starts by looking first for a server on its own machine); or it could be based on load balance (a CICS client is bound in such a way that uniform responsiveness for all clients is attempted).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A distributed service may employ &lt;strong&gt;data replication&lt;/strong&gt;, where a service maintains multiple copies of data to permit local access at multiple locations, or to increase availability when a server process may have crashed. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt; is a related concept and very common in distributed systems. We say a process has cached data if it maintains a copy of the data locally, for quick access if it is needed again.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;strong&gt;cache hit&lt;/strong&gt; is when a request is satisfied from cached data, rather than from the primary service. &lt;/p&gt;
&lt;p&gt;For example, browsers use document caching to speed up access to frequently used documents.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The difference between caching and replication: Caching is similar to replication, but cached data can become stale. Thus, there may need to be a policy for 
validating a cached data item before using it. If a cache is actively refreshed by the primary service, caching is identical to replication.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;Internet Protocol (IP)&lt;/strong&gt; suite is the set of communication protocols that allow for communication on the Internet and most commercial networks. The &lt;strong&gt;Transmission Control Protocol (TCP)&lt;/strong&gt; is one of the core protocols of this suite. Using TCP, clients and servers can create connections to one another, over which they can exchange data in packets. The protocol guarantees reliable and in-order delivery of data from sender to receiver.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The IP suite can be viewed as a set of layers, each layer having the property that it only uses the functions of the layer below, and only exports functionality to the layer above. A system that implements protocol behavior consisting of layers is known as a &lt;strong&gt;protocol stack&lt;/strong&gt;. Protocol stacks can be implemented either in hardware or software, or a mixture of both. Typically, only the lower layers are implemented in hardware, with the higher layers being implemented in software.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There are four layers in the IP suite (top-down):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Application Layer&lt;/strong&gt; : The application layer is used by most programs that require network communication. Data is passed down from the program in an application-specific format to the next layer, then encapsulated into a transport layer protocol. Examples of applications are HTTP, FTP or Telnet.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transport Layer&lt;/strong&gt; : The transport layer’s responsibilities include end-to-end message transfer independent of the underlying network, along with error control, fragmentation and flow control. End-to-end message transmission at the transport layer can be categorized as either__connection-oriented (TCP)&lt;strong&gt; or 
__connectionless (UDP)&lt;/strong&gt;: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;TCP is the more sophisticated of the two protocols, providing reliable delivery. First, TCP ensures that the receiving computer is ready to accept data. It uses a three-packet handshake in which both the sender and receiver agree that they are ready to communicate. Second, TCP makes sure that data gets to its destination. If the receiver doesn’t acknowledge a particular packet, TCP automatically retransmits the packet typically three times. If necessary, TCP can also split large packets into smaller ones so that data can travel reliably between source and destination. TCP drops duplicate packets and rearranges packets that arrive out of sequence.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UDP is similar to TCP in that it is a protocol for sending and receiving packets across a network, but with two major differences. First, it is connectionless. This means that one program can send off a load of packets to another, but that’s the end of their relationship. The second might send some back to the first and the first might send some more, but there’s never a solid connection. UDP is also different from TCP in that it doesn’t provide any sort of guarantee that the receiver will receive the packets that are sent in the right order. All that is guaranteed is the packet’s contents. This means it’s a lot faster, because there’s no extra overhead for error-checking above the packet level. For this reason, games often use this protocol. In a game, if one packet for updating a screen position goes missing, the player will just jerk a little. The other packets will simply update the position, and the missing packet - although making the movement a little rougher - won’t change anything.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Although TCP is more reliable than UDP, the protocol is still at risk of failing in many ways. TCP uses acknowledgements and retransmission to detect and repair loss. But it cannot overcome longer communication outages that disconnect the sender and receiver for long enough to defeat the retransmission strategy. The normal maximum disconnection time is between 30 and 90 seconds. TCP could signal a failure and give up when both end-points are fine. This is just one example of how TCP can fail, even though it does provide some mitigating strategies.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;img alt="tcp" class="img-responsive" src="/images/tcp.jpg"/&gt;
&lt;img alt="udp" class="img-responsive" src="/images/udp.jpg"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Network Layer&lt;/strong&gt; : As originally defined, the Network layer solves the problem of getting packets across a single network. With the advent of the concept of internetworking, additional functionality was added to this layer, namely getting data from a source network to a destination network. This generally involves routing the packet across a network of networks, e.g. the Internet. IP performs the basic task of getting packets of data from source to destination.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Link Layer&lt;/strong&gt; : The link layer deals with the physical transmission of data, and usually involves placing frame headers and trailers on packets for travelling over the physical network and dealing with physical components along the way.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remote-procedure-calls"&gt;Remote Procedure Calls&lt;/h2&gt;
&lt;p&gt;Over time, an efficient method for clients to interact with servers evolved called RPC, which means &lt;strong&gt;remote procedure call&lt;/strong&gt;. It is a powerful technique based on extending the notion of local procedure calling, so that the called procedure may not exist in the same address space as the calling procedure. The two processes may be on the same system, or they may be on different systems with a network connecting them.&lt;/p&gt;
&lt;p&gt;An RPC is similar to a function call. Like a function call, when an RPC is made, the arguments are passed to the remote procedure and the caller waits for a response to be returned. In the illustration below, the client makes a procedure call that sends a request to the server. The client process waits until either a reply is received, or it times out. When the request arrives at the server, it calls a dispatch routine that performs the requested service, and sends the reply to the client. After the RPC call is completed, the client process continues.&lt;/p&gt;
&lt;p&gt;&lt;img alt="rpc" class="img-responsive" src="/images/rpcpix.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;Threads are common in RPC-based distributed systems. Each incoming request to a server typically spawns a new thread. A thread in the client typically issues an RPC and then blocks (waits). When the reply is received, the client thread resumes execution. A programmer writing RPC-based code does three things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Specifies the protocol for client-server communication&lt;/li&gt;
&lt;li&gt;Develops the client program&lt;/li&gt;
&lt;li&gt;Develops the server program&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The communication protocol is created by stubs generated by a protocol compiler. A &lt;strong&gt;stub&lt;/strong&gt; is a routine that doesn’t actually do much other than declare itself and the parameters it accepts. The stub contains just enough code to allow it to be compiled and linked.&lt;/p&gt;
&lt;p&gt;The client and server programs must communicate via the procedures and data types specified in the protocol. The server side registers the procedures that may be called by the client and receives and returns data required for processing. The client side calls the remote procedure, passes any required data and receives the returned data.&lt;/p&gt;
&lt;p&gt;Thus, an RPC application uses classes generated by the stub generator to execute an RPC and wait for it to finish. The programmer needs to supply classes on the server side that provide the logic for handling an RPC request.&lt;/p&gt;
&lt;p&gt;RPC introduces a set of error cases that are not present in local procedure programming. For example, a binding error can occur when a server is not running when the client is started. Version mismatches occur if a client was compiled against one version of a server, but the server has now been updated to a newer version. A timeout can result from a server crash, network problem, or a problem on a client computer.&lt;/p&gt;
&lt;p&gt;Some RPC applications view these types of errors as unrecoverable. Fault-tolerant systems, however, have alternate sources for critical services and fail-over from a primary server to a backup server.&lt;/p&gt;
&lt;p&gt;A challenging error-handling case occurs when a client needs to know the outcome of a request in order to take the next step, after failure of a server. This can sometimes result in incorrect actions and results. For example, suppose a client process requests a ticket-selling server to check for a seat in the orchestra section of Carnegie Hall. If it’s available, the server records the request and the sale. But the request fails by timing out. Was the seat available and the sale recorded? Even if there is a backup server to which the request can be re-issued, there is a risk that the client will be sold two tickets, which is an expensive mistake in Carnegie Hall.&lt;/p&gt;
&lt;p&gt;Here are some common error conditions that need to be handled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Network data loss resulting in retransmit&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Often, a system tries to achieve ‘at most once’ transmission tries. In the worst case, if duplicate transmissions occur, we try to minimize any damage done by the data being received multiple time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Server process crashes during RPC operation&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;If a server process crashes before it completes its task, the system usually recovers correctly because the client will initiate a retry request once the server has recovered. If the server crashes completing the task but before the RPC reply is sent, duplicate requests sometimes result due to client retries.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Client process crashes before receiving response&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Client is restarted. Server discards response data.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="distributed-design-principles"&gt;Distributed Design Principles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As Ken Arnold says: “You have to design distributed systems with the expectation of failure.” Avoid making assumptions that any component in the system is in a particular state. A classic error scenario is for a process to send data to a process running on a second machine. The process on the first machine receives some data back and processes it, and then sends the results back to the second machine assuming it is ready to receive. Any number of things could have failed in the interim and the sending process must anticipate these possible failures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explicitly define failure scenarios and identify how likely each one might occur. Make sure your code is thoroughly covered for the most likely ones.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Both clients and servers must be able to deal with unresponsive senders/receivers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Think carefully about how much data you send over the network. Minimize traffic as much as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Latency is the time between initiating a request for data and the beginning of the actual data transfer. Minimizing latency sometimes comes down to a question of whether you should make many little calls/data transfers or one big call/data transfer. The way to make this decision is to experiment. Do small tests to identify the best compromise.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don’t assume that data sent across a network (or even sent from disk to disk in a rack) is the same data when it arrives. If you must be sure, do checksums or validity checks on data to verify that the data has not changed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Caches and replication strategies are methods for dealing with state across components. We try to minimize stateful components in distributed systems, but it’s challenging. State is something held in one place on behalf of a process that is in another place, something that cannot be reconstructed by any other component. If it can be reconstructed it’s a cache. Caches can be helpful in mitigating the risks of maintaining state across components. But cached data can become stale, so there may need to be a policy for validating a cached data item before using it. If a process stores information that can’t be reconstructed, then problems arise. One possible question is, “Are you now a single point of failure?” I have to talk to you now - I can’t talk to anyone else. So what happens if you go down? To deal with this issue, you could be replicated. Replication strategies are also useful in mitigating the risks of maintaining state. But there are challenges here too: What if I talk to one replicant and modify some data, then I talk to another? Is that modification guaranteed to have already arrived at the other? What happens if the network gets partitioned and the replicants can’t talk to each other? Can anybody proceed? There are a set of tradeoffs in deciding how and where to maintain state, and when to use caches and replication. It’s more difficult to run small tests in these scenarios because of the overhead in setting up the different mechanisms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Be sensitive to speed and performance. Take time to determine which parts of your system can have a significant impact on performance: Where are the bottlenecks and why? Devise small tests you can do to evaluate alternatives. Profile and measure to learn more. Talk to your colleagues about these alternatives and your results, and decide on the best solution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Acks are expensive and tend to be avoided in distributed systems wherever possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Retransmission is costly. It’s important to experiment so you can tune the delay that prompts a retransmission to be optimal.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="system"></category><category term="papers"></category><category term="distributed systems"></category><category term="system design principle"></category><category term="system concepts"></category></entry><entry><title>How to write binary search correctly</title><link href="https://zhu45.org/posts/2018/Jan/12/how-to-write-binary-search-correctly/" rel="alternate"></link><published>2018-01-12T16:24:00+08:00</published><updated>2018-01-12T16:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2018-01-12:/posts/2018/Jan/12/how-to-write-binary-search-correctly/</id><summary type="html">&lt;p&gt;How to write a binary search correctly on the first try&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#introduction"&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#term-explanation"&gt;Term explanation&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#invariant"&gt;Invariant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#bound-function"&gt;Bound function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#precondition-and-postcondtion"&gt;Precondition and postcondtion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#binary-search"&gt;Binary search&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#problem-statement"&gt;Problem statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation"&gt;Implementation&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#implementation-1"&gt;Implementation 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation-2"&gt;Implementation 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#binary-search-variations"&gt;Binary search variations&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#example-1"&gt;Example 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#example-2"&gt;Example 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion"&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Binary search is a straightforward algorithm to understand but it is hard to code it right.
This is especially true given the forms of implementation on binary search can take on many.
In addition, there are many problems can be solved by binary search with slight adjustment.
Thus, it is not feasible to simply memorize the template of implementation without understanding.
In this post, We illustrate how we can use the loop invariant in combination with pre and
postcondition to code binary search correctly. One thing to note is that this post is drafted for 
practical purpose and it may not be theoretical rigorous.&lt;/p&gt;
&lt;h2 id="term-explanation"&gt;Term explanation&lt;/h2&gt;
&lt;h3 id="invariant"&gt;Invariant&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://reprog.wordpress.com/2010/04/25/writing-correct-code-part-1-invariants-binary-search-part-4a/"&gt;Mike’s post&lt;/a&gt; 
has an excellent description of &lt;a href="https://en.wikipedia.org/wiki/Invariant_(computer_science)"&gt;invariant&lt;/a&gt;, which I 
directly paste below:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An invariant is a property that remains true throughout the execution of a piece of code.  It’s a statement about the state of a program — primarily the values of variables — that is not allowed to become false.  (If it does become false, then the code is wrong.)  Choosing the correct invariant — one that properly expresses the intent of an algorithm — is a key part of the design of code (as opposed to the design of APIs); and ensuring that the invariant remains true is a key part of the actual coding.  Roughly speaking, if your invariant properly expresses the intent of the algorithm, and if your code properly maintains the invariant, then that is enough for you to be confident that the code, if it terminates, yields the correct answer.  (Ensuring that it does in fact terminate is the job of the bound function.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, an invariant is a condition that can be relied upon to be true during execution of a program, or during some portion of it. 
In practice, we formalize that invariant in terms of specific variables and values that appeared in the algorithm.&lt;/p&gt;
&lt;h3 id="bound-function"&gt;Bound function&lt;/h3&gt;
&lt;p&gt;Again, &lt;a href="https://reprog.wordpress.com/2010/04/27/writing-correct-code-part-2-bound-functions-binary-search-part-4b/"&gt;Mike’s post&lt;/a&gt; has a nice
explanation of &lt;a href="https://en.wikipedia.org/wiki/Loop_variant"&gt;bound function&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The bound function of a loop is defined as an upper bound on the number of iterations still to perform.  More generally, you can think of it as an expression whose value decreases monotonically as the loop progresses.  When it reaches zero (or drops below), you exit the loop.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="precondition-and-postcondtion"&gt;Precondition and postcondtion&lt;/h3&gt;
&lt;p&gt;We borrow definition from &lt;a href="https://reprog.wordpress.com/2010/04/30/writing-correct-code-part-3-preconditions-and-postconditions-binary-search-part-4c/"&gt;Mike’s post&lt;/a&gt; once again:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you invoke a function — or, all right, a method — you have a sense of what needs to be true when you invoke it, and what it guarantees to be true when it returns.  For example, when you call a function oneMoreThan(val), you undertake to ensure that val is an integer, and the function undertakes to ensure that the value it returns is one more than the one you passed in.  These two promises — the precondition and postcondition — constitute the contract of the function.  So:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The precondition is the promise that you make before running a bit of code;&lt;/li&gt;
&lt;li&gt;The postcondition is the promise that the code makes after it’s been run.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id="binary-search"&gt;Binary search&lt;/h2&gt;
&lt;h3 id="problem-statement"&gt;Problem statement&lt;/h3&gt;
&lt;p&gt;Before we actually implement our algorithm, we first need to make sure we understand the problem correctly. By understanding, we need to make
sure we understand the given input and the expectation of the output. Those will be translated into the precondition and postcondition for our algorithm.
Precondition helps us to design the algorithm and postcondition helps us to make sure we get the intended result.&lt;/p&gt;
&lt;p&gt;Binary search problem is following: given an integer &lt;span class="math"&gt;\(X\)&lt;/span&gt; and integers &lt;span class="math"&gt;\(A_0, A_1, \dots, A_{N-1}\)&lt;/span&gt;, which are presorted in ascending order, find
&lt;span class="math"&gt;\(i\)&lt;/span&gt; such that &lt;span class="math"&gt;\(A_i = X\)&lt;/span&gt;, or return &lt;span class="math"&gt;\(i = -1\)&lt;/span&gt; if &lt;span class="math"&gt;\(X\)&lt;/span&gt; is not in the input. There might be multiple of &lt;span class="math"&gt;\(i\)&lt;/span&gt; with &lt;span class="math"&gt;\(A_i = X\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="implementation"&gt;Implementation&lt;/h3&gt;
&lt;p&gt;The invariant for our binary search algorithm is: “if the target value &lt;span class="math"&gt;\(X\)&lt;/span&gt; is present in the array, then the target value is present in the current range.”
As mentioned above, invariant is formalized using specific variables and values. Here, we need to decide the representation of “current range”. This is
the place where the binary search has many ways of implementation. We use &lt;code&gt;low&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; to define the range and we use &lt;code&gt;n&lt;/code&gt; to denote the length of array.
There are several popular formalization of the “current range”:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Number 2 and 4 are the invariants that behind two most popular implementation of binary search you can find on the internet. &lt;/p&gt;
&lt;h4 id="implementation-1"&gt;Implementation 1&lt;/h4&gt;
&lt;p&gt;For 2, the equation means that &lt;span class="math"&gt;\(i \in [\text{low}, \text{high})\)&lt;/span&gt;. Thus, &lt;code&gt;low&lt;/code&gt; is initialized to &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; initialized to &lt;code&gt;n&lt;/code&gt;. Thus, the invariant
for this is “If &lt;span class="math"&gt;\(X\)&lt;/span&gt; is at any position &lt;span class="math"&gt;\(i\)&lt;/span&gt; in &lt;span class="math"&gt;\(A\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(A_i = X\)&lt;/span&gt;) then &lt;code&gt;low &amp;lt;= i &amp;lt; high&lt;/code&gt;”. The implementation represents this invariant is below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;binarySearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# X &amp;lt; A[i]&lt;/span&gt;
            &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to show the correctness of the above implementation, we need to make sure that we maintain the invariant through the execution of the function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first thing is to establish the invariant that’s going to hold true for the rest of the function, so we set the variables &lt;code&gt;low&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; to appropriate values (i.e. the lowest and one pass the highest indexes of the whole &lt;span class="math"&gt;\(A\)&lt;/span&gt;).&lt;/li&gt;
&lt;li&gt;We have ensured that the invariant is true when we first enter the loop. To show that stays true throughout the running of the function, we need to show that whenever it’s true at the top of the loop, it’s also true at the bottom. Here, our invariant is also the loop invariant.&lt;/li&gt;
&lt;li&gt;The first statement of the loop (assigning to &lt;code&gt;i&lt;/code&gt;) does not affect any of the variables referenced by the invariant, so it can’t possibly cause the invariant to stop being true.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What follows is a three-way &lt;code&gt;if&lt;/code&gt; statement: we need to show that each of the three branches maintains the invariant.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The first branch (i.e., &lt;code&gt;X == A[i]&lt;/code&gt;) covers the case where we have found the target. At this point, we’re returning from the function (and therefore breaking out of the loop) so we don’t really care about the invariant any more; but for what it’s worth, it remains true, as we don’t change the values of &lt;code&gt;low&lt;/code&gt; or &lt;code&gt;high&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The second branch (i.e., &lt;code&gt;X &amp;gt; A[i]&lt;/code&gt;) is the first time we need to use non-trivial reasoning.  If we’re in this branch, we know that the condition guarding it was true (i.e., &lt;code&gt;X &amp;gt; A[i]&lt;/code&gt;).  But because &lt;code&gt;A&lt;/code&gt; is sorted in ascending order, we know that for all &lt;span class="math"&gt;\(j &amp;lt; i, A[j] &amp;lt;= A[i]\)&lt;/span&gt;. 
This means that &lt;span class="math"&gt;\(X\)&lt;/span&gt; &amp;gt; all A[j] with &lt;span class="math"&gt;\(j &amp;lt;= i\)&lt;/span&gt;. Thus, the lowest position the target can be at is &lt;code&gt;A[i+1]&lt;/code&gt;. In addition, since our invariant is &lt;span class="math"&gt;\(i \in [low, high)\)&lt;/span&gt;,
we can set &lt;code&gt;low&lt;/code&gt; to &lt;code&gt;i+1&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;The third branch follows the same form as the second: since we know that &lt;code&gt;X &amp;lt; A[i]&lt;/code&gt; and that &lt;span class="math"&gt;\(A[j] &amp;gt;= A[i] \forall j &amp;gt; i\)&lt;/span&gt;, we know the highest position the 
target can be at is &lt;code&gt;A[i-1]&lt;/code&gt;. However, our invariant insists that &lt;span class="math"&gt;\(i \in [low, high)\)&lt;/span&gt; with &lt;code&gt;high&lt;/code&gt; being exclusive brace. Thus, we cannot set &lt;code&gt;high&lt;/code&gt; to be &lt;code&gt;i-1&lt;/code&gt;
and instead, we set it to &lt;code&gt;i&lt;/code&gt;. Doing so, we maintain our invariant unchanged.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since we’ve verified that all three branches of the &lt;code&gt;if&lt;/code&gt; maintain the invariant, we know that the invariant holds on exiting that &lt;code&gt;if&lt;/code&gt;. That means the invariant is
true at the bottom of the loop, which means it will be true at the start of the next time around the loop. And by induction we deduce that it always remains true.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Finally, we break out of the loop when &lt;code&gt;low &amp;lt; high&lt;/code&gt; is false, which means that the candidate range is empty (i.e. &lt;code&gt;low == high&lt;/code&gt;). At this point, we know that the condition of the invariant (“If &lt;span class="math"&gt;\(X\)&lt;/span&gt; is at any position &lt;span class="math"&gt;\(i\)&lt;/span&gt; in &lt;span class="math"&gt;\(A\)&lt;/span&gt;”) does not hold, so the invariant is trivially true; and we return the out-of-band value &lt;code&gt;-1&lt;/code&gt;. &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implementation-2"&gt;Implementation 2&lt;/h4&gt;
&lt;p&gt;For 4, the equation means that &lt;span class="math"&gt;\(i \in [\text{low}, \text{high}]\)&lt;/span&gt;. Thus, &lt;code&gt;low&lt;/code&gt; is initialized to &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; initialized to &lt;code&gt;n-1&lt;/code&gt;. Thus, the invariant
for this is “If &lt;span class="math"&gt;\(X\)&lt;/span&gt; is at any position &lt;span class="math"&gt;\(i\)&lt;/span&gt; in &lt;span class="math"&gt;\(A\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(A_i = X\)&lt;/span&gt;) then &lt;code&gt;low &amp;lt;= i &amp;lt;= high&lt;/code&gt;”. The implementation represents this invariant is below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;binarySearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="https://reprog.wordpress.com/2010/04/25/writing-correct-code-part-1-invariants-binary-search-part-4a/"&gt;Mike’s post&lt;/a&gt; has done the similar invariant unchanged
analysis, which I’ll skip for this implementation. Until now, we haven’t touched on the concept of “bound function” and “postcondition” in our analysis. However,
that doesn’t mean these two concepts are not important. Usually, “bound function” is used to prove our loop terminates (Mike’s post talks about how to use 
“bound function” to show above implementation terminates; TopCoder link gives an example of why we need to show algorithm actually terminates). 
Next section, we’ll see an example of checking postcondition is important to make sure we have correct return result.&lt;/p&gt;
&lt;h2 id="binary-search-variations"&gt;Binary search variations&lt;/h2&gt;
&lt;p&gt;In this section, we’ll talk about two examples that use binary search and see how we can implement the binary search correctly if we are able to maintain the
invariant. &lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1&lt;/h3&gt;
&lt;p&gt;The first example is &lt;a href="https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/"&gt;LC153. Find Minimum in Rotated Sorted Array&lt;/a&gt;.
Here, we are asked to find the minimum element given the rotated array. Suppose we have array &lt;code&gt;[0,1,2,4,5,6,7]&lt;/code&gt; and there are seven ways of rotation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;7&lt;/span&gt;
&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;
&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;5&lt;/span&gt;
&lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;
&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;
&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;
&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The key observation is that if the middle value is greater than the left value, then the minimum value appears on the righthand-side of the middle value
(i.e., for &lt;code&gt;[4,5,6,7,0,1,2]&lt;/code&gt;, the middle value is &lt;code&gt;7&lt;/code&gt; and the minimum value &lt;code&gt;0&lt;/code&gt; appears on the righthand-side of &lt;code&gt;7&lt;/code&gt;).
Otherwise, the minimum value appears on the lefthand-side of the middle value. Like the previous section, we need to define &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; and then our invariant.
Here, we define the &lt;code&gt;left&lt;/code&gt; as the &lt;code&gt;0&lt;/code&gt; index of the array and &lt;code&gt;right&lt;/code&gt; as the last index of the array. Then, our invariant can be formulated as: “the index of minimum
value (i.e., &lt;span class="math"&gt;\(i\)&lt;/span&gt;) is always contained in the subarray denoted by &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; (i.e., &lt;span class="math"&gt;\(i \in [\text{left}, \text{right}]\)&lt;/span&gt;)”. In addition, our precondition
is: an array sorted in ascending order is rotated at some pivot unknown. Our postcondition is: the minimum value. Then, our implementation is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;findMin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# nums[mid] &amp;lt; nums[left]&lt;/span&gt;
            &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We verify our invariant unchanged as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The invariant is unchanged before the first &lt;code&gt;if&lt;/code&gt; when &lt;code&gt;nums[left] &amp;lt; nums[right]&lt;/code&gt;. Here, we know that there is no rotation in the array (i.e.,
&lt;code&gt;[0,1,2,3,4,5,6,7]&lt;/code&gt;) and we return &lt;code&gt;nums[left]&lt;/code&gt;, which keeps invariant and satisfy the postcondition.&lt;/li&gt;
&lt;li&gt;For the second &lt;code&gt;if&lt;/code&gt;: when &lt;code&gt;nums[mid] &amp;gt;= nums[left]&lt;/code&gt;, by our observation, we know that the minimum value appears 
on the righthand-side of the middle value. &lt;code&gt;mid&lt;/code&gt; value cannot be the minimum because &lt;code&gt;nums[mid] &amp;gt;= nums[left]&lt;/code&gt;. Thus, we can set &lt;code&gt;left&lt;/code&gt; to &lt;code&gt;mid + 1&lt;/code&gt;
and still maintains our invariant unchanged.&lt;/li&gt;
&lt;li&gt;For the case when &lt;code&gt;nums[mid] &amp;lt; nums[left]&lt;/code&gt;, we know that the minimum value appear on the lefthand-side of the middle value. However, &lt;code&gt;mid&lt;/code&gt; value 
can be the minimum value and thus we set &lt;code&gt;right&lt;/code&gt; to &lt;code&gt;mid&lt;/code&gt; to maintain the invariant.&lt;/li&gt;
&lt;li&gt;The loop exit when &lt;code&gt;left == rigt&lt;/code&gt;. Our invariant is &lt;span class="math"&gt;\(i \in [\text{left}, \text{right}]\)&lt;/span&gt;, which is different from postcondition requires: 1. postcondition
asks us to return the actual minimum value instead of the index 2. We still haven’t found the minimum value yet. The invariant states that
&lt;span class="math"&gt;\(i \in [\text{left}, \text{right}]\)&lt;/span&gt;, which is &lt;span class="math"&gt;\(i \in [\text{left}, \text{left}]\)&lt;/span&gt; given &lt;code&gt;left == right&lt;/code&gt;. Thus, minimum value can only appear on index pointed by
&lt;code&gt;left&lt;/code&gt; and to meet the postcondition requirement, we &lt;code&gt;return nums[left]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usually, for the iterative algorithm, the invariant is the same as the loop invariant. However, this example also shows the power of the postcondition. In the 
basic binary search above, maintaining the invariant naturally gives us the result that meets the postcondition requirement. However, for this example, our invariant
doesn’t give us the required result. By checking the postcondition, we know what’s the expected return is and it also indicates how we can find one.&lt;/p&gt;
&lt;h3 id="example-2"&gt;Example 2&lt;/h3&gt;
&lt;p&gt;The second example we are asked to find the index of the first number that is greater than the given target number in the array. Like basic binary search problem,
the array is sorted in ascending order. As always, let’s consider some examples for this problem. Suppose we are given an array &lt;code&gt;[0,1,5,7,8,10,12,15]&lt;/code&gt;, if the
target number is &lt;code&gt;3&lt;/code&gt;, we should return &lt;code&gt;2&lt;/code&gt;, which is the index of the first number that is greater than &lt;code&gt;3&lt;/code&gt; (i.e., &lt;code&gt;5&lt;/code&gt;). What about the target number is &lt;code&gt;16&lt;/code&gt;?
In this case, there is no number in the array is greater than the target number, and we should return &lt;code&gt;-1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What’s the invariant for this problem? Similar to the other binary search problem, the invariant is “the index &lt;span class="math"&gt;\(i\)&lt;/span&gt; of the first number that is greater than
the given target number in the array is in &lt;span class="math"&gt;\([\text{low}, \text{high}]\)&lt;/span&gt;”. Thus, we can initialize &lt;code&gt;low&lt;/code&gt; to be &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; to be &lt;code&gt;n&lt;/code&gt;. Note that we set &lt;code&gt;high&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt; instead of &lt;code&gt;n-1&lt;/code&gt; due to the need to maintain the invariant: for the case when there is no number in the array that is greater than the target number, we can think about
the first number that is greater than the target number happens one past the last index. Then, by our invariant, we need to include that number. Thus, we set our &lt;code&gt;high&lt;/code&gt; to &lt;code&gt;n&lt;/code&gt; instead of &lt;code&gt;n-1&lt;/code&gt;. The implementation is following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;findFirstGreaterTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# nums[mid] &amp;gt; target&lt;/span&gt;
            &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mid&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The invariant is maintained as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Invariant is unchanged until the first &lt;code&gt;if&lt;/code&gt;: &lt;code&gt;nums[mid] &amp;lt;= target&lt;/code&gt;. There are two cases here: when &lt;code&gt;nums[mid] &amp;lt; target&lt;/code&gt;, since the array is sorted in
ascending order and we are looking for the number that is greater than the target number, thus we can set &lt;code&gt;low&lt;/code&gt; to &lt;code&gt;mid + 1&lt;/code&gt; without breaking the invariant.
When &lt;code&gt;nums[mid] == target&lt;/code&gt;, again we are looking for the first number that is greater than the target number, thus we can set &lt;code&gt;low&lt;/code&gt; to &lt;code&gt;mid + 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When &lt;code&gt;nums[mid] &amp;gt; target&lt;/code&gt;, we can set &lt;code&gt;high&lt;/code&gt; to &lt;code&gt;mid&lt;/code&gt; to maintain our invariant.&lt;/li&gt;
&lt;li&gt;The loop exit when &lt;code&gt;low == high&lt;/code&gt;, since our invariant is the index of the first number greater than the target number is in &lt;span class="math"&gt;\([\text{low}, \text{high}]\)&lt;/span&gt;, which
is &lt;span class="math"&gt;\([\text{high}, \text{high}]\)&lt;/span&gt; in this case. Our invariant still holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Here is a reasoning why &lt;code&gt;low&lt;/code&gt; cannot be greater than &lt;code&gt;high&lt;/code&gt; when the loop exits: suppose that &lt;code&gt;low&lt;/code&gt; is greater than &lt;code&gt;high&lt;/code&gt;
on loop exit. The only possible case that &lt;code&gt;low&lt;/code&gt; is greater than &lt;code&gt;high&lt;/code&gt; is when &lt;span class="math"&gt;\(\text{low} = {mid^0}+1\)&lt;/span&gt; and &lt;span class="math"&gt;\(\text{high} = {mid^{-1}}\)&lt;/span&gt; where &lt;span class="math"&gt;\({mid^0}\)&lt;/span&gt; means the &lt;code&gt;mid&lt;/code&gt; value of the current iteration (i.e., immediately before loop exit) and &lt;span class="math"&gt;\(mid^{-1}\)&lt;/span&gt; means the &lt;code&gt;mid&lt;/code&gt; value of the previous iteration. Then, we want to show &lt;span class="math"&gt;\(mid^0 + 1 &amp;gt; mid^{-1}\)&lt;/span&gt;. &lt;span class="math"&gt;\(\text{mid}^0\)&lt;/span&gt; is cacluated from &lt;span class="math"&gt;\((\text{low}^{-1} + \text{mid}^{-1})/2\)&lt;/span&gt; assuming in the last iteration, &lt;code&gt;low&lt;/code&gt; is changed to &lt;span class="math"&gt;\(\text{mid}^0+1\)&lt;/span&gt; (the other case works similarly). &lt;span class="math"&gt;\(\text{low}^{-1}\)&lt;/span&gt; is less than &lt;span class="math"&gt;\(\text{mid}^{-1}\)&lt;/span&gt; because otherwise we already exit the while loop. Thus, &lt;span class="math"&gt;\(\text{mid}^0\)&lt;/span&gt; is smaller than &lt;span class="math"&gt;\(\text{mid}^{-1}\)&lt;/span&gt;. The minimum difference between &lt;span class="math"&gt;\(\text{mid}^0\)&lt;/span&gt; and &lt;span class="math"&gt;\(\text{mid}^{-1}\)&lt;/span&gt; is 1 and thus &lt;code&gt;low&lt;/code&gt; cannot be greater than &lt;code&gt;high&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once we exit the loop, we need to check our postcondition once again. Our postcondition asks us the index of the first number that is greater than the target number
if it is in the array and &lt;code&gt;-1&lt;/code&gt; otherwise. However, during the initialization of &lt;code&gt;high&lt;/code&gt;, we consider &lt;code&gt;n&lt;/code&gt; represents the case when no such number exists and at the same
time, satisfies our invariant. Thus, before returning the result, we need to check whether &lt;code&gt;high&lt;/code&gt; within the index range of the given array to satisfy the
postcondition constraint.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this post, we take a look at the technique that helps us implement the binary search correctly: maintain the invariant. Also, we emphasize the importance
of the postcondition to help us get the returen result correctly. We haven’t empahsized the importance of bound function in the post but we should consider
it as well. There are two ways to check the loop indeed terminates: one is through reasoning similar what we have done in invariant analysis 
(&lt;a href="https://reprog.wordpress.com/2010/04/27/writing-correct-code-part-2-bound-functions-binary-search-part-4b/"&gt;Mike’s post&lt;/a&gt; and 
&lt;a href="http://coldattic.info/post/95/"&gt;Paul’s post&lt;/a&gt; give us examples on how to do that); another way is by considering some special cases like there are only two 
elements in the array suggested by the TopCoder article below.&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt; Some details are left out in this post: 1. why use &lt;code&gt;mid = low + (high - low)//2&lt;/code&gt; instead of
&lt;code&gt;mid = (low + high) // 2&lt;/code&gt; &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt; 2. Use &lt;code&gt;A[low] &amp;lt;= A[i] &amp;lt;  A[high]&lt;/code&gt; as an invariant is better than &lt;code&gt;A[low] &amp;lt;= A[i] &amp;lt;= A[high]&lt;/code&gt;. &lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/504335/what-are-the-pitfalls-in-implementing-binary-search"&gt;StackOverflow - What are the pitfalls in implementing binary search?&lt;/a&gt; (has a short explanation of the importance of invariant with an example)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/26564658/binary-search-and-invariant-relation"&gt;StackOverflow - Binary search and invariant relation&lt;/a&gt; (has a nice example)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/"&gt;TopCoder - Binary Search&lt;/a&gt; (think about binary search through predicate inquiry)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.eecs.yorku.ca/course_archive/2013-14/W/2011/lectures/09%20Loop%20Invariants%20and%20Binary%20Search.pdf"&gt;Loop Invariants and Binary Search&lt;/a&gt; 
(Nice illustration (i.e., “safe place”) between precondition, loop invariant, postcondition)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www-inst.cs.berkeley.edu/~cs170/fa14/tutorials/tutorial1.pdf"&gt;Invariants and Proofs of correctness&lt;/a&gt; (Gives relative formalization of our invariant
analysis in the post. Essentially, invariant is the same as the inductive hypothesis.)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.cornell.edu/courses/cs2110/2014sp/L12-Sorting/L12cs2110BSearchInvariants.pdf"&gt;Binary search and loop invariants&lt;/a&gt; (Slide 6 is good: it tells us how 
to setup the terminate condition of the loop. Loop terminates when the invariant looks like the postcondition. This slide also gives example of writing terminate
condition as &lt;code&gt;while(low != high - 1)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.cornell.edu/courses/cs2112/2015fa/lectures/lec_loopinv/index.html"&gt;Loop invariants&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The rigorous analysis on this binary search implementation can be found from &lt;a href="https://www.cs.cmu.edu/~rjsimmon/15122-s13/06-binsearch.pdf"&gt;Frank’s lecture notes on binary search&lt;/a&gt;. He encodes &lt;a href="https://www.cs.cmu.edu/~rjsimmon/15122-s13/02-contracts.pdf"&gt;contract&lt;/a&gt; 
directly into the implementation, which displays the loop invariant, precondition, and postcondition directly. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Topcoder article offers an equivalent thought of thinking about invariant: predicate inquiry. For example, our last example invariant can be translated
into the predicate: “Is &lt;code&gt;nums[i]&lt;/code&gt; greater than the target number?” Then, each element is tagged with either “yes” or “no”. Then, the problem asks us to find
out the first element has tag “yes”. The two elements special case shown in the article is “no,yes” array. Details see the article. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;The explanation can be found on &lt;a href="https://rosettacode.org/wiki/Binary_search"&gt;Rosettacode page&lt;/a&gt; and 
&lt;a href="https://www.cs.cmu.edu/~rjsimmon/15122-s13/06-binsearch.pdf"&gt;Frank’s lecture notes on binary search on page L6.12&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;&lt;a href="https://reprog.wordpress.com/2010/04/21/binary-search-redux-part-1/#comment-2178"&gt;A comment on Mike’s post&lt;/a&gt; sheds some insights. &lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="algorithm"></category><category term="leetcode"></category></entry><entry><title>Crowdsourcing readings</title><link href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/" rel="alternate"></link><published>2017-12-30T12:30:00+08:00</published><updated>2017-12-30T12:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-12-30:/posts/2017/Dec/30/crowdsourcing-readings/</id><summary type="html">&lt;p&gt;CS 395T Human Computation / Crowdsourcing papers reading&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#intro"&gt;Intro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-human-processing-unit-hpu"&gt;“The Human Processing Unit (HPU)”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#soylent-a-word-processor-with-a-crowd-inside"&gt;“Soylent: A Word Processor with a Crowd Inside”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#crowd-based-fact-checking"&gt;“Crowd-based Fact Checking”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#improving-twitter-search-with-real-time-human-computation"&gt;“Improving Twitter Search with Real-Time Human Computation”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#platemate-crowdsourcing-nutritional-analysis-from-food-photographs"&gt;“Platemate: crowdsourcing nutritional analysis from food photographs”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#an-introduction-to-crowdsourcing-for-language-and-multimedia-technology-research"&gt;“An introduction to crowdsourcing for language and multimedia technology research”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#imagenet-large-scale-visual-recognition-challenge"&gt;“ImageNet Large Scale Visual Recognition Challenge”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#visual-dialog"&gt;“Visual Dialog”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#vqa-visual-question-answering"&gt;“VQA: Visual Question Answering”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#zooniverse-observing-the-worlds-largest-citizen-science-platform"&gt;“Zooniverse: observing the world’s largest citizen science platform”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#practical-lessons-for-gathering-quality-labels-at-scale"&gt;“Practical Lessons for Gathering Quality Labels at Scale”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#crowdsourcing-user-studies-with-mechanical-turk"&gt;“Crowdsourcing user studies with Mechanical Turk”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#automan-a-platform-for-integrating-human-based-and-digital-computation"&gt;“Automan: A platform for integrating human-based and digital computation”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#beyond-mechanical-turk-an-analysis-of-paid-crowd-work-platforms"&gt;“Beyond Mechanical Turk: An Analysis of Paid Crowd Work Platforms”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#instrumenting-the-crowd-using-implicit-behavioral-measures-to-predict-task-performance"&gt;“Instrumenting the crowd: using implicit behavioral measures to predict task performance”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#mmmturkey-a-crowdsourcing-framework-for-deploying-tasks-and-recording-worker-behavior-on-amazon-mechanical-turk"&gt;“MmmTurkey: A Crowdsourcing Framework for Deploying Tasks and Recording Worker Behavior on Amazon Mechanical Turk”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#amazons-turker-crowd-has-had-enough"&gt;“AMAZON’S TURKER CROWD HAS HAD ENOUGH”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-future-of-work-caring-for-the-crowdworker-going-it-alone"&gt;“The Future of Work: Caring for the Crowdworker Going It Alone”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-good-the-bad-and-the-ugly-why-crowdsourcing-needs-ethics"&gt;“The Good, The Bad and the Ugly: Why Crowdsourcing Needs Ethics”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#information-extraction-and-manipulation-threats-in-crowd-powered-systems"&gt;“Information Extraction and Manipulation Threats in Crowd-Powered Systems”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#exploitation-in-human-computation-systems"&gt;“Exploitation in Human Computation Systems”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#dirty-deeds-done-dirt-cheap-a-darker-side-to-crowdsourcing"&gt;“Dirty Deeds Done Dirt Cheap: A Darker Side to Crowdsourcing”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;
&lt;p&gt;This post contains reflections for part of the papers I have read in Prof. &lt;a href="https://www.ischool.utexas.edu/~ml/"&gt;Matt Lease&lt;/a&gt;‘s 
&lt;a href="http://courses.ischool.utexas.edu/Lease_Matt/2017/Fall/INF385T/"&gt;Human Computation course&lt;/a&gt;.
To get a full list of papers, see the &lt;a href="https://docs.google.com/document/d/1f4jN-Cnk9ceVSIyMMvf8yMRu3j6aBxEyemilLvVcBSU/edit"&gt;course schedule&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="the-human-processing-unit-hpu"&gt;“The Human Processing Unit (HPU)”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://users.soe.ucsc.edu/~orazio/papers/DavisACVHL_CVPR10.pdf"&gt;The Human Processing Unit (HPU)&lt;/a&gt; Davis, J. et al. (2010). Computer Vision &amp;amp; Pattern Recognition (CVPR) Workshop on Advancing Computer Vision with Humans in the Loop (ACVHL). 8 pages.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This paper looks interesting because it tries to develop a hybrid framework that, at least conceptually, allows integration between manpower (i.e., 
HPU) and computer power (i.e., CPU). I think the biggest accomplishment this paper has achieved is providing a new perspective to evaluate old 
problems. By directly comparing human with the computer, the authors essentially take a retrospective view on the development of “computer” term, 
which starts out as a way to describe an occupation and then gradually evolved into a term for a specific type of machine. They suggest that it is 
time to view “computer” as a human-integrated electronic device in order to solve the problems that cannot be solved perfectly by the CPU-driven 
computer alone. Their idea of applying old terms in a new context really makes me think whether this paradigm can be applied to other fields of 
research.&lt;/p&gt;
&lt;p&gt;However, there are several concerns I want to raise when I read through the paper. One of the contributions claimed in the paper is that 
“characterizing the HPU as an architectural platform”. I think the statement is too aggressive. For example, when the authors use color labeling 
task as a way to demonstrate the accuracy between HPU and CPU, I find that essentially they outsource the task that should be done by machine 
learning algorithms to human and CPU just perform some basic statistical work. It seems that the paper suggests us to abandon the use of machine 
learning algorithms for certain tasks and let HPU do the work. I think HPU is a way to improve machine learning algorithms from 90% accuracy to 100% 
accuracy. We still want the CPU-based algorithms to play the major role in the system because the CPU-based algorithm is proved to be stable and low 
latency in a well-tuned production system. In addition, some characterization of HPU cannot be generalized, which prevents people from benchmarking 
HPU against CPU in a straightforward way. For example, the paper shows an empirical study of cost versus accuracy on a specific task, which cannot 
be fully generalized to other scenarios. This makes authors’ claim on crowdsourcing as a new architecture for production systems vulnerable because 
there is no clear way to estimate the performance of HPU. Furthermore, many critical questions related to securities and performance need to be 
addressed before we can use HPU in a production system. For example, what would happen if the task sent to the HPU contains confidential information 
and this piece of information is critical for people finishing the task? How do we design the task to workaround this problem? How do we handle the 
problem that HPU can take several minutes, several hours or even several days to finish a certain task? How can we ensure the quality of HPU 
computation result?&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="soylent-a-word-processor-with-a-crowd-inside"&gt;“Soylent: A Word Processor with a Crowd Inside”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://projects.csail.mit.edu/soylent/"&gt;Soylent: A Word Processor with a Crowd Inside&lt;/a&gt;
Bernstein, M. et al., UIST 2010. Best Student Paper award. Reprinted in Communications of the ACM, August 2015.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Overall, I think this paper can be treated as a concrete example to support the HPU paper’s idea because Soylent uses crowdsourcing to carry out a 
complex but meaningful task: editing, which goes beyond the commonly-seen crowdsourcing task: labeling the training data for machine learning 
algorithms. The tool shows an example of how powerful crowdsourcing can become once we get the HPU and CPU (i.e., word processor) fully integrated. 
One example I really like is about crowdsourced proofreading. Unlike the clueless Microsoft Word message “Fragment; consider revising”, with the 
help from the crowd, we can get the meaningful explanation of the mistakes for different errors we make in the writing. This example also surprises 
me because I’m wondering how many crowd workers will take much effort writing out the explanation of the errors. Unlike usual crowdsourcing task, 
which is about clicking several buttons for the survey, writing the explanation can be much more demanding. In addition, I really like the “related 
work” section of the paper because it lists several crowdsourcing examples and I actually want to try some of them: for instance, the HelpMeOut tool 
for debugging code through collecting traces. &lt;/p&gt;
&lt;p&gt;There are a couple of questions and thoughts I want to list out when I read through this paper. One is that I’m wondering how effective the 
Crowdproof will be if we do not pay out any money at all? In HPU paper, the authors use shirt color task as an example to show that there is no 
strong correlation between how much you pay for the crowd and the accuracy you can get from the task. I’m wondering if this statement will hold 
under crowdsourced proofreading setting. In addition, I want to learn more about The Human Macro because one of the design challenges, as pointed 
out in the paper, is to define the task scope for crowd worker. However, from the paper, it seems that all of the responsibility falls on the user’s 
shoulder. Is there any way from the system-side that can help the user better tailor their task for the crowd worker? When the authors talk about 
how to prevent the worker from being lazy on the task, they cite a paper by Kittur et al. that says adding “clearly verifiable, quantitative 
questions”. I am wondering how can they do that in their system because if they use this methodology, then they must use a way to automate the 
question generation because once the writer triggers the Soylent, the crowdsourcing tasks should be triggered automatically, which requires the 
question gets automatically generated. Question generation can be hard because it needs some level of text comprehension and I am really curious 
what is the type of method the authors use in their system. Also, similar to HPU paper, this paper does not dive into the details of how we can 
tackle the privacy (security) and the latency issues in order to make the system robust in real production.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="crowd-based-fact-checking"&gt;“Crowd-based Fact Checking”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Crowd-based Fact Checking. An T. Nugyen.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The big picture of this paper is clear to me. The author wants to automate the process of determining the correctness of claims, which referred as 
fact-checking in the field. Initially, I was confused about how the fact-checking works in reality. However, after browsing through some websites 
listed in the paper, for example, Politifact, the goal that the author tries to achieve becomes clear to me. In addition, I can tell how the author 
knits the crowdsourcing with the machine learning algorithms to develop a hybrid method. Basically, there are two sets of training data that the 
author leverages: one has the journalist label and the other has the label from crowdsourcing. Then the data with journalist label is for the 
off-line scenario, which does not require the machine learning algorithm gives the real-time fact-checking result. Crowdsourcing data is used as a 
way to approximate the journalist “gold standard” in the online scenario, where we trade some level of accuracy for the performance of 
fact-checking. This paper also links to the Soylent paper in the sense that this paper also mentions how to prevent “lazy worker” scenario from 
happening. Specifically, inside “Crowdsourced labels collection”, the author requires workers to give an explanation to their label.&lt;/p&gt;
&lt;p&gt;My questions for this paper majorly come from the technical perspectives. I have some basic understanding of PGM and BN but clearly, that is not 
enough for this paper. EM algorithm, Gibbs sampling, Variational Inference, softmax are concepts that confuse me the most. In addition, the 
unfamiliarity of the field makes me wonder what exactly is the “independent models” that the author refers to when he talks about the baseline for 
his new model. Those questions lead to a bigger and more generic question regarding research and this course: how should we approach the 
mathematical-dense paper like this in the early phase of the graduate study (i.e., first semester of graduate school)? Hopefully, during the lecture 
this week, we can have some time to talk about this question. In addition to those technical questions, I’m wondering how good the variational 
method works. As mentioned in the “Results” section, the difference between the variational method and the baseline diminishes as more crowd labels 
get collected. This makes me wonder if the new model is really as good as the author claims. Are we paying too much price (i.e., time and 
computational cost) to pursue a mediocre complicated model when a simple model can deliver the similar performance? &lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="improving-twitter-search-with-real-time-human-computation"&gt;“Improving Twitter Search with Real-Time Human Computation”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.twitter.com/engineering"&gt;Improving Twitter Search with Real-Time Human Computation&lt;/a&gt;. Edwin Chen and Alpa Jain. &lt;a href="https://blog.twitter.com/engineering"&gt;Twitter Engineering Blog&lt;/a&gt;. January 8, 2013.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This article is interesting because it offers a real world example of how we can integrate crowdsourcing into the real production system. 
The problems associated with crowdsourcing are usually related to the performance and latency. Performance often refers to the accuracy
of tasks that crowd workers finish and latency usually measures the amount of time that takes from the tasks start to finish. In the papers
I have read so far, researchers merely come up with good solutions to tackle these two issues and thus, the architecture or the product
that they come up cannot be directly applied in the real world. That’s why this article looks interesting because Twitter actually uses
crowdsourcing in their production system. The way that Twitter handles these two issues is centered around the people. Quite often, when
there is a crowdsourcing task, people immediately think about Amazon Mechanical Turk or Crowdflower. However, what Twitter does is that
they use these third-party platforms as backups and they mainly use “custom pool”, which contains a group of crowd workers (or “judges”) that
are highly specialized to Twitter product scenarios. This solution may look expensive initially because “for many of them, this is a full-time job” 
and thus, I hardly think Twitter just pay around 0.07 dollars for tasks these people finish. However, I think this solution saves a lot of
economics cost. For example, as pointed out in this article, those judges are recruited to handle the short-term search query spike and annotate
the new trend of the search query. This means the latency is the key here: it is not acceptable for a crowdsourcing task spends several hours or days
to finish, which are commonly-seen for standard crowdsourcing tasks through those third party platforms. Furthermore, even the crowd workers fair
quickly, the accuracy of the task result can hardly be guaranteed because crowd workers can possibly misunderstand the meaning of the query due
to the sudden appearance of the trend. From the quality control perspective, we devote a lot of
statistical methods or human intervention to improve the quality of crowdsourcing jobs in a standard setting, which may seem unnecessary for Twitter settings because
those people in the pool are highly-trained professionals. If we think from Twitter perspective, any mistake has the potential to cost multi-million 
advertisement revenue and thus, it is not hard to imagine why Twitter chooses to use their own in-house “turkers”.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;There is also an article called &lt;a href="http://blog.echen.me/2014/10/07/moving-beyond-ctr-better-recommendations-through-human-evaluation/"&gt;Moving Beyond CTR: Better Recommendations Through Human Evaluation&lt;/a&gt;, which comes
from one of the author from above article, is also worth checking out.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="platemate-crowdsourcing-nutritional-analysis-from-food-photographs"&gt;“Platemate: crowdsourcing nutritional analysis from food photographs”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.eecs.harvard.edu/~kgajos/papers/2011/noronha-platemate-uist11.pdf"&gt;Platemate: crowdsourcing nutritional analysis from food photographs&lt;/a&gt; 
Noronha, Jon, Eric Hysen, Haoqi Zhang, &amp;amp; Krzysztof Gajos. UIST 2011 pp. 1-12.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The paper is interesting from several perspectives. First, the problem described in the paper is important to tackle. There are plenty of food tracking applications online but many of them 
require the tedious manual logging, which requires a fair amount of effort from the User. Can we make the whole process easier to people? In addition, many HIT design tricks have been mentioned 
in the paper. For instance, when we ask the crowd workers to identify food items in a photo, we may want to provide several examples to them to guide their work. Another trick mentioned is that 
we may need to pay attention to the subtlety of the task design in the sense that we want to break the task into its atomic form. For example, when the authors ask the workers to identify the 
food inside the database, the workers have two tasks mentally: identify the food and locate the food in the database. We want these two tasks carried out separately by different groups of 
Tuckers. One trick to my amusement is to disable keyboard quick selection, which is quite important to prevent “lazy worker” but easy to forget during the task design.&lt;/p&gt;
&lt;p&gt;There are also several questions I want to ask. Latency is still a big issue for human computation. Specifically for this paper, the nutrition estimates will return to the user within a few 
hours. In the evaluation section, the average time takes to finish analysis is 94.14 minutes, which is quite long. In addition, this service costs $1.40 per photo, which can cost $1533 per year 
(i.e., three meals per day for 365 days). Given the cost and performance of the tool, I can hardly imagine this application will become popular to a wide audience. This leads to the problem 
caused by the methodology of research. This paper puts heavy weights on the human computation and less on the computer-based algorithmic approach. This is confirmed by the author inside the 
discussion section of the paper. To me, Kitamura et al. really gets close to solving the problem: they can successfully identify whether the photo contains food and the categories of food. The 
major piece left out is to identify the specific foods and the actual intake. I think the former one can be done with computer approach as well and the latter one may invoke crowd sourcing. Doing 
this way may improve the performance of the whole application and reduce the cost of invoking too many crowdsourcing tasks. Furthermore, inside the “Step 1: Tag”, the authors mention that “a 
combination of machine and human computation is used to select the better box group” without actually mentioning the exact methodology they use. I’m wondering what exactly the method is. In 
addition, the paper has limitation rooted in Amazon Mechanical Turk. The problem is that only the Americans can use this platform and thus, inevitably, a certain bias will introduce to the 
research. In particular, this paper states that “We chose to require American Turkers due to the unique cultural context required for most elements of the process.” In other words, PlateMate is 
only applicable to the food that is well-understood by the American culture, which is partially confirmed by the evaluation photos that the authors use. All those photos contain the food that is 
commonly-seen in the United States. What about the food from other countries with a dramatically different cultural background? Can the component of the food be still easily understood by the 
American-based crowd? In my opinion, the answer is probably no and the nutrition estimate accuracy may drop significantly if we use the tool from different parts of the world. The limit of Amazon 
Mechanical Turk, which seems to be the de-facto standard for crowdsourcing research nowadays, poses the constraint on the research result as well. How do we accommodate this issue is worth to 
think about.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="an-introduction-to-crowdsourcing-for-language-and-multimedia-technology-research"&gt;“An introduction to crowdsourcing for language and multimedia technology research”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://doras.dcu.ie/17876/3/pws_crowdsoucing_final.pdf"&gt;An introduction to crowdsourcing for language and multimedia technology research&lt;/a&gt;.
Gareth Jones. PROMISE Winter School 2012. Springer, pp. 132-154.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This paper is centered around using crowdsourcing as a way for data collection. Specifically, it targets 
at language and multimedia technology research, which majorly involves natural language processing and 
computer vision respectively. The paper provides extensive examples of how crowdsourcing can be utilized 
as a way for gathering the data. There are several good points made in this paper. First of all, the 
author provides examples on the definition of crowdsourcing. Crowdsourcing can be applied in various 
fields. Quite often, I have a hard time to come up examples that do not belong to crowdsourcing. The 
example provided by the author is the crowd management at a sports event, in which recruiting more members 
from the crowd is not ideal. The paper also shows the recurring principles in crowdsourcing task design: 
“identify an activity which is amenable to being broken into small elemental tasks”. Lastly, the paper 
provides many pointers to the crowdsourcing resources and the papers that focus on the specific area of 
crowdsourcing task design (i.e., Payment and Incentives), which are good for future in-depth study.&lt;/p&gt;
&lt;p&gt;There are several questions I want to ask after reading through the paper. I’m still confused about the 
exact mechanism of the quality control of the crowdsourcing task. In the paper, the author states that 
“Once the quality of the work has been checked, the requester then has the option to accept the work and 
make payment to the worker, or to reject it, in which case payment is not made.” I’m wondering if the 
requester can exploit this checking-submission mechanism to gather the data while not paying out the 
money. Since the work can be checked, the requester can duplicate the work result and rejected the work. 
Certainly, this will damage the requester’s reputation in the long run, but the requester can use this 
mechanism as a way to do budget control. Another question regarding quality control is how we can check 
the quality of the work without traversing all the submission. The paper does not show how RSR task 
handles this issue. One way the author suggests to do quality control is to come up the “honey pots” 
questions, which have known answers to the requester. I’m wondering what fraction of the work that 
contains “honey pots” questions will cause the false positive. Based on my experience with CrowdFlower, I 
feel some “honey pots” questions are too hard to get right. Then, under this situation, how we can 
distinguish between spammers and the workers that actually put the effort into the task.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="imagenet-large-scale-visual-recognition-challenge"&gt;“ImageNet Large Scale Visual Recognition Challenge”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/pdf/1409.0575.pdf"&gt;ImageNet Large Scale Visual Recognition Challenge&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Latency is a big problem in crowdsourcing. Usually, the crowdsourcing tasks will take several days or weeks to finish. Is there any way to speed up the whole process and reduce the latency of the response without sacrificing much on the quality of the tasks? One idea is to build a cache between the application and the crowdsourcing platform, which using the machine learning techniques to identify the similarity between two given tasks and using the crowd to do the optional verification of the two tasks to make sure those tasks are indeed similarly or even the same. Then, we can reuse the task result from the previous to speed up the whole crowdsourcing process. &lt;/p&gt;
&lt;p&gt;ImageNet is a legendary example of crowdsourcing. There is a plenty of media coverage on this challenge. The paper shows how the team from the Stanford compose this benchmark dataset and how this dataset changes the landscape of the computer vision. The essential task of benchmarking dataset is that it has to provide sufficient accuracy so that researchers can use it to train and evaluate their learning algorithms. This necessarily poses a big challenge to the designing of the crowdsourcing task: how do we collect 1,461,406 images and correctly annotate them for different computer vision task? &lt;/p&gt;
&lt;p&gt;One principle is to design the crowdsourcing tasks that targets at specific goals. There are three goals for this dataset: image classification, single-object localization, and object detection. For image classification dataset annotation, we can utilize the voting system for crowdsourcing task. However, for single-object localization annotation, we may want to apply different crowdsourcing principles by making the tasks “as simple as possible” and “has a fixed and predictable amount of work”. In addition, insights from the goal may help us to design the crowdsourcing task better. One example is the authors find out that “different categories require different levels of consensus among users.” For example, the number of crowd workers required to verify cat images is less than the number of crowd workers required for Burmese cat images. This can save the researchers a decent amount of the budget on crowdsourcing tasks. Another example on this matter is the hierarchical algorithm they developed for multi-class annotation. In addition to those details, I find some interesting papers for my future reading on this topic: “Crowdsourcing annotations for visual object detection” and “Scalable multi-label annotation” are interesting to check out. Lastly, the authors compare the machine-based algorithm with the human annotators and show that how human can still beat the computer in the computer vision task. I think it is a strong evidence in showing how good the HPU can be.&lt;/p&gt;
&lt;p&gt;For a survey paper like this, some details get omitted but are interesting to ask from crowdsourcing perspective. When the authors evaluate the image classification dataset annotation, they “manually checked 1500 ILSVRC 2012-2014 image classification test set images”. My question is how do they sample those 1500 images? How do they translate 5 annotation errors from those images into “99.7% precision”? In addition, they “visually” check the accuracy of bounding box for single-object localization dataset, I’m wondering if this checking procedure is rigorous enough? Computer is known for its human-unmatched level of accuracy. The bounding box may be good in terms of human eyes but may not be true from computer’s perspective.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="visual-dialog"&gt;“Visual Dialog”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/pdf/1611.08669.pdf"&gt;Visual Dialog&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Visual Dialog is extremely similar to usual chatbot except that the chat is centered around the images provided. Unlike VQA, visual dialog focuses on the dialogue which requires a list of chat history regarding the picture that both the bot and the human talks about. I play around the live demo of this paper online, and I find that the bot is extremely good at image caption. I uploaded a cat picture looks like below and the bot immediately captions the picture with the title “a cat is standing in a window sill”. However, in terms of the details of the image, the bot seems not really good at it. One question I asked is “what’s inside the sill?” and the bot replied “orange and white”. Then, I asked “How many cats are there?” the bot replied “2”. To me, the bot has difficulty to do object detection correctly and it is really hard for me to keep the conversation going.
One thing I find this paper is really cool is their AMT task design. Before reading this paper, my idea is limited in terms of what kinds of the task that can be performed on Amazon Turk. I have never thought of “hosting a live two-person chat on AMT” and the authors even build their own “backend messaging and data-storage infrastructure based on Redis messaging queues and Node.js”. The interface they design is quite clean and can meet their goal. However, I think they can make this into a game to motivate people to actively get involved in the conversation. Besides the task design, I get a sense of what we should talk about when we collect some data for the paper. Basically, we need to give out the statistics and analysis of the data set by listing out the components of the data set, the distribution of the questions we asked or collected, the answers we got, and so on.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="vqa-visual-question-answering"&gt;“VQA: Visual Question Answering”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/pdf/1505.00468v6.pdf"&gt;VQA: Visual Question Answering&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;VQA is an AI task that combines the Computer Vision (CV) with the Natural Language Processing (NLP). The user can ask the questions that are best answered based on the image provided. The paper has several interesting points. The first is their crowdsourced task design. The researchers try to pose the questions in a way that can “elicit the most interesting and diverse questions”. One sentence I really like in their “smart robot” interface is “Your task is to stump this smart robot!” I certainly want to come up tricky questions that can beat the researchers’ “evil” robot. From this, I learned that the instruction text also impacts the quality of the crowdsourcing tasks. The goal to the crowdsourcing in this task is to get as many diverse questions as possible. Carefully crafting instruction text is one way, and the other way is to better design the questions appeared in the survey. One trick the researchers use is “when writing a question, the subjects were shown the previous questions already asked for that image to increase the question diversity”. One important idea I learned from this paper is doing the question analysis of the dataset. In the paper when the researchers come up the question answers for the crowdsourcing task, they employ the machine learning technique to compose their “18 candidate answers”. For example, they “gather additional answers from nearest neighbor questions using a bag-of-words model”. In addition to the question analysis, the researchers also study the impact of the task interface design on their data set collected. In Appendix I, the researchers study the spatial relationship between the text and the image. These design practices make me think if there is a way to decide the good strategy of the task design. Statistically speaking, what’s the effective way to design a survey (i.e. crowdsourcing task).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="zooniverse-observing-the-worlds-largest-citizen-science-platform"&gt;“Zooniverse: observing the world’s largest citizen science platform”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://wwwconference.org/proceedings/www2014/companion/p1049.pdf"&gt;Zooniverse: observing the world’s largest citizen science platform&lt;/a&gt;. Robert Simpson et al., WWW 2014 companion, pp. 1049-1054. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Zooniverse project looks both similar and different from the crowdsourcing platforms that we have seen so far in the semester. The similarity comes from both the Zooniverse and Amazon Mechanical Turk, for example, involve the data collection. On both platforms, the crowd can “identify, classify, mark, and label” the data. However, Zooniverse is different from AMT in the sense that they “brand” their platform as a place to perform “citizen science”, which can bring much more potential from the crowd than AMT, which is perceived as a place to perform the job and get the money. One example is the “Mutual Muses” project that the crowd is asked to “transcribe Correspondence by  Critic Lawrence Alloway and Artist Sylvia Sleigh”. Surely, on AMT, requesters can still post the tasks that are the same to this. But, branding the data collection process as a citizen science project can make the crowd much more attentive to the work they do. Unlike other crowdsourcing platforms, the Zooniverse takes a holistic approach to the crowd. The projects I have browsed so far do not have “quiz mode” but well-crafted tutorials. The interface design is much more modern and the project itself is “cooler” than the tasks found on the AMT or Crowdflower. One thing I notice that is on the Zooniverse, people are told about the mission of the project but on the AMT, the crowd is barely informed what the data is used for, which makes the platform feel like a place to earn some extra cash not a place to help with research.
The architecture introduction of the Zooniverse platform is uninteresting from the crowd perspective but is definitely worth reading for people who want to build a platform for large-scale crowdsourcing tasks. One point I really like is that the authors are well-aware of “The creation of engaging user experiences is essential to getting the best from volunteers online”, which makes me much appreciated after working with Crowdflower and AMT platforms. Zooniverse’s smooth working process and the mission of the projects make me forget that most of the work I do on the platform is actually without compensation. Near the end of the paper, the authors discuss the potential of the data visualization. I think it is really a great idea especially when the platform treats the crowd not as “workers” but as “researchers”.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="practical-lessons-for-gathering-quality-labels-at-scale"&gt;“Practical Lessons for Gathering Quality Labels at Scale”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Alonso, O. (2015). &lt;a href="http://dl.acm.org/ft_gateway.cfm?id=2776778&amp;amp;type=pdf"&gt;Practical Lessons for Gathering Quality Labels at Scale&lt;/a&gt;. 38th International ACM SIGIR Conference on Research and Development in Information Retrieval (pp. 1089-1092). &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Alonso (2015) gathers the practical lessons for designing large-scale crowdsourcing task. There are many good tips mentioned inside the paper that are invaluable resources for the crowdsourcing task design. For example, besides the instruction rules, showing examples is a good way to make the crowd worker productive with a meaningful result. Also, the HIDDEN structure proposed in the paper answers my doubts about how to check the performance of the workers if the gold set is missing. In addition, the “honey pots” strategy is mentioned inside the paper and the author uses it as a way to remove incapable workers at the beginning of the task and to perform random checks during the task execution.
Some questions are also worth asking. For example, I am very glad to see that the bias problem gets mentioned by the author in his “data-worker-task” debugging framework. However, how we can handle those bias is a totally different issue and somehow the author does not dive into details. I think that is may be due to the complexity of the issue and the detailed discussion may not fit into the whole framework. However, without some concrete suggestions on how to handle the bias, the proposed framework does not look concrete for me. Another question comes from the comparison between inter-rate static and the percentage agreement. Specifically, I’m wondering what is the drawback of using the percentage agreement statistic? How can we measure whether an inter-rater static is good or bad? Overall, I really like this paper as it provides a very crucial overview on the crowdsourcing task design and it gives a list of questions that we researchers may want to ask during the task design.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="crowdsourcing-user-studies-with-mechanical-turk"&gt;“Crowdsourcing user studies with Mechanical Turk”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Kittur, A., Chi, E. H., &amp;amp; Suh, B. (2008, April). &lt;a href="http://kittur.org/files/Kittur+2008_CrowdsourcingMechanicalTurk.pdf"&gt;Crowdsourcing user studies with Mechanical Turk&lt;/a&gt;. In Proceedings of the SIGCHI conference on human factors in computing systems (pp. 453-456).&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Kittur et al., (2008) perform an actual user study on the crowdsourcing. Like Alonso’s paper, many tips for crowdsourcing task design give out in the paper: integration of the verifiable questions, minimization of the effort gap between spammers and the good workers, and various ways of detection of the suspect responses. However, the authors in “Crowdsourcing user studies with Mechanical Turk” also carry out the tips they list into two experiments. I’m really surprised to learn how significant the crowdsourcing task design can be on the end result. In addition, the authors also provide some measurements of the crowd we are facing on the platform. Specifically, instead of commonly-believed “widespread gaming”, only a small fraction of people are actually spammers. The rest of the crowd do not have the incentive to finish the task carelessly at the very beginning but might become eventually due to the ill-design of the crowdsourcing task. This observation of the crowd further confirms the importance of the crowdsourcing task design.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="automan-a-platform-for-integrating-human-based-and-digital-computation"&gt;“Automan: A platform for integrating human-based and digital computation”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://cacm.acm.org/magazines/2016/6/202648-automan/fulltext"&gt;Automan: A platform for integrating human-based and digital computation&lt;/a&gt;.
Barowy, Daniel W., Charlie Curtsinger, Emery D. Berger, and Andrew McGregor.  Communications of the ACM 59, no. 6 (2016): 102-109.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This paper takes a different angle to look at the crowdsourcing task design, which involves designing a programming language that wraps the crowdsourcing tasks details under function calls. The greatest benefit in doing so is that it provides a unified interface to the programmer so that the programmer does not need to worry about the underlying crowdsourcing task design too much, which makes the whole program portable. In other words, we can tune the configuration of AUTOMAN to make the whole application works for different goals using different crowdsourcing platforms. Another benefit provided by the crowdsourcing programming language abstraction is the better task design experience. Normally, without the abstraction, we may need to design both the task content and also comes up the mechanism to perform the quality control. However, now, with the benefit of function call implementation of the crowdsourcing, we can put all our effort on the crowdsourcing task content design (i.e., Specific questions to the crowd) instead of designing the whole workflow from the beginning to the end, which can save people’s a fair amount of time.
There are still some questions worth asking about the programming language implementation. For example, for the free-text input, the current implementation uses the pattern matching to verify the worker input and perform the probability analysis for the quality. However, there seems no semantic analysis of the response provided by the worker. This reflects one of the shortcomings for the paper’s programming language implementation for the crowdsourcing task: some parts of the crowdsourcing tasks cannot be fully automated as part of the system. In other words, for the free-text input, people still need to go into the actual text to see the semantic meaning of the response. This is especially important when the programming language supports quality control mechanism. Without understanding the meaning of the response, one can hardly assess its quality.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="beyond-mechanical-turk-an-analysis-of-paid-crowd-work-platforms"&gt;“Beyond Mechanical Turk: An Analysis of Paid Crowd Work Platforms”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Donna Vakharia and Matthew Lease. &lt;a href="http://www.ischool.utexas.edu/~ml/papers/donna-iconf15.pdf"&gt;Beyond Mechanical Turk: An Analysis of Paid Crowd Work Platforms&lt;/a&gt;. In Proceedings of the iConference, 2015. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The paper provides a detailed comparison among seven crowdsourcing platforms. One noticeable phenomenon I observed in the papers we have read so far is that all of them perform their work on AMT. That makes AMT a de-facto standard for crowdsourcing and human computation research. One possible motivation for researchers using AMT for the work is that AMT is well-understood by the research community. The limitation and functionality of the platform is known to the community and the researcher do not have to go through the platform introduction before jumping into their actual contribution. However, as suggested in the paper, using AMT solely can problematic. One consequence is that the diversity of the research will be limited due to the constraint posed by the platform.  Thus, in order to encourage the community to adopt various crowdsourcing platforms for the research, a survey of existing crowdsourcing platforms is a must and I’m very happy that I can read a paper like this one. Survey of the existing platforms can also provide a practical guide for researchers to pick the platform that is best suited for their goals. For example, we do not have to reinvent the wheels by building some fancy infrastructure for complex tasks on AMT if other platforms like WorkFusion and CloudFactory have already built the tools that can be used out-of-box. However, I think the paper can encourage the researchers to try out different platforms more if it can provide some typical usage scenarios that are best suited for each platform. Some platform like CloudFactory can be quite different from the AMT in the sense that CloudFactory puts more emphasis on the enterprise users than the individual requesters. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="instrumenting-the-crowd-using-implicit-behavioral-measures-to-predict-task-performance"&gt;“Instrumenting the crowd: using implicit behavioral measures to predict task performance”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jeffrz.com/wp-content/uploads/2010/08/fp359-rzeszotarski.pdf"&gt;Instrumenting the crowd: using implicit behavioral measures to predict task performance&lt;/a&gt;. Jeffrey Rzeszotarski and Aniket Kittur. ACM UIST Conference, pp. 13-22, 2011.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In the paper, the authors talk about how we can utilize the meta information about MTurk tasks to predict the quality of the work done by the crowd. This is very useful for quality control because we always want to remove the lazy workers from our workforce. That is why we study different quality control techniques throughout the semester. In the paper, the authors think by logging interface data (i.e., mouse, keystrokes, response time), we can predict the quality of the work using machine learning techniques. There are a couple of questions with this method. First, there is a natural latency in making prediction for the quality control purpose. In the paper, the logging data is uploaded via an opt-in button near the end of the task and then they perform all the data mining work backend. However, the spammers are unlikely to submit their logging data to the remote and the data mining work takes time to finish. During the time, the good workers may switch to other tasks. In the paper, the authors think that one prediction model trained for one task can be applied towards the similar tasks. I think it can remove the latency to some degree but it is hard for requesters to distinguish when the direct application of models can work and when the pre-trained models can introduce unseen errors. Second, we cannot remove the bad workers solely based on the prediction result. There is a false positive risk that we may remove the good workers due to the data inaccuracy caused by the “cross-browser compatibility” issue. So, I think the prediction model still belongs to the post-hoc class and it seems ineffective to me that instead of targeting at the work the workers done, we focus on study how each worker behave. However, I think the models proposed in the paper is useful when we handle the data generated by certain workers that fall onto the borderline of deciding whether the work is good or bad.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="mmmturkey-a-crowdsourcing-framework-for-deploying-tasks-and-recording-worker-behavior-on-amazon-mechanical-turk"&gt;“MmmTurkey: A Crowdsourcing Framework for Deploying Tasks and Recording Worker Behavior on Amazon Mechanical Turk”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://arxiv.org/abs/1609.00945"&gt;MmmTurkey: A Crowdsourcing Framework for Deploying Tasks and Recording Worker Behavior on Amazon Mechanical Turk&lt;/a&gt;.
Brandon Dang, Miles Hutson, and Matthew Lease. In 4th AAAI Conference on Human Computation and Crowdsourcing (HCOMP): Works-in-Progress Track, 2016. 3 pages. arXiv:1609.00945. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In the second paper, the authors propose a framework called MmmTurkey that is built on top of the Mechanical Turk, which allows the requesters to easily customize their tasks and at the same time logging the workers’ behaviors. I find the framework looks particularly promising especially for the requesters who want to deeply customize their HIT tasks while keeping track of the workers’ behaviors to perform quality control. I’m curious how exactly the framework works under the hood? Can it replace AMT completely in the sense that I can post the HIT tasks from MmmTurkey interface and wait for the result? I see the paper seems to agree with my thinking but I’m just wondering if there are any corner cases I need to be aware of?&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="amazons-turker-crowd-has-had-enough"&gt;“AMAZON’S TURKER CROWD HAS HAD ENOUGH”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;MIRANDA KATZ. &lt;a href="https://www.wired.com/story/amazons-turker-crowd-has-had-enough/"&gt;AMAZON’S TURKER CROWD HAS HAD ENOUGH&lt;/a&gt;. WIRED: BACKCHANNEL. August 23, 2017.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In the first article, the author describes the MTurk and crowdsourcing in general from the workers’ perspectives. The idea is simple: the workers will deliver their best work given a good compensation and transparent communication. The message characterizes the future of the crowdsourcing industry in that MTurk is still has its advantages and the platform will dominate the industry if it can take much more of the workers and make the communication clearer. In addition, the article argues that simply replicating the MTurk with some minor additions to the functionalities will not sustain long in the industry. I agree with the author in that building a reliable platform has to be organization and community driven. This is not saying that academia effort like Daemo is worthless. Academia is very good at building innovative prototypes. However, in order for the platform to be scalable and robust, some large community or organization effort has to come in. From this perspective, MTurk has the clear edge over the other competitors.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-future-of-work-caring-for-the-crowdworker-going-it-alone"&gt;“The Future of Work: Caring for the Crowdworker Going It Alone”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.psmag.com/business-economics/the-future-of-work-caring-for-the-crowdworker-going-it-alone"&gt;The Future of Work: Caring for the Crowdworker Going It Alone&lt;/a&gt; (blog post). Mary Gray (Microsoft Research), Pacific Standard, August 21, 2015.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The second article shares the big picture with the previous one. On one hand, they focus on the traditional crowdsourcing platforms with microtasks. On the other hand, they expand the crowdsourcing term more broadly to the on-demand sharing economy, which includes Uber, Airbnb as well. This article specifically describes the future of the crowdsourcing platform, which should center around the workers. Compensation is not the only factor that the future crowdsourcing platforms should take care. Third-party registry that allows the workers build their resume and healthcare should be also valued just like the regular 40-hour employees.&lt;/p&gt;
&lt;h2 id="the-good-the-bad-and-the-ugly-why-crowdsourcing-needs-ethics"&gt;“The Good, The Bad and the Ugly: Why Crowdsourcing Needs Ethics”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.researchgate.net/profile/Florian_Schmidt12/publication/261126823_The_Good_The_Bad_and_the_Ugly_Why_Crowdsourcing_Needs_Ethics/links/02e7e537c5e2662206000000.pdf"&gt;The Good, The Bad and the Ugly: Why Crowdsourcing Needs Ethics&lt;/a&gt;. Schmidt, F. A. (2013, September). In Cloud and Green Computing (CGC), 2013 Third International Conference on (pp. 531-535). IEEE.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This paper reminds me of the HPU paper we read very early in the semester. HPU tends to think the crowd like machines, which can work like CPU. However, framing the crowd like this inevitably injecting the impression that the crowd can be treated cheaply. This impression is exactly what the paper tries to address. The paper categorizes the crowdsourcing behaviors based on the crowd’s incentives. Then, the paper studies some platforms and show how they try to exploit their workers’ incentives and treat them cheaply. These three readings make me think that we cannot treat crowdsourcing as a way to get the task done cheaply. We also need to take care of people that make all those great contributions to the advancement of civilization. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="information-extraction-and-manipulation-threats-in-crowd-powered-systems"&gt;“Information Extraction and Manipulation Threats in Crowd-Powered Systems”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Lasecki, Walter S., Jaime Teevan, and Ece Kamar. &lt;a href="https://github.com/ipeirotis/Mturk-Tracker/"&gt;Information Extraction and Manipulation Threats in Crowd-Powered Systems&lt;/a&gt;. CSCW 2014. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this paper, the authors talk about different forms of threats specifically on extracting information from the crowd-based systems and manipulating the systems’ outcomes. One example of information extraction is that the workers can extract the sensitive information (i.e., credit card number) from given picture for an image labeling task. Another example is that if the workers collaboratively mislabel the images, the machine learning algorithm based on the crowdsourced training data can lead to the wrong output. In the paper, the authors present several ways of preventing data leakage. One approach is the division of a task into micro-tasks. The idea is that we do not want each worker to see too much information. However, there can be a consequence of this approach is that the workers may get manipulated by the requesters to do the things that violate their will. One example mentioned by Caverlee is that Iran’s leaders use workers to cross-reference the faces of the citizens with those of photographed demonstrators. The authors further subdivide the information extraction threats into exposure, exploitation, and reconstruction. In addition, they classify the answer manipulation into classic manipulation, disruption, and corruption. Those threats are viewed from the requester’s’ perspective. This paper makes me appreciate the importance of the quality control more and we need to pay extra attention to the sensitive information presented in the images. I think we somehow need to run the preliminary check of the data that are put onto the crowdsourcing platform.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="exploitation-in-human-computation-systems"&gt;“Exploitation in Human Computation Systems”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Caverlee, James. Exploitation in Human Computation Systems. In Springer Handbook of Human Computation, pp. 837-845, 2013. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this paper, the author surveys the exploitation of the human computation system from three perspectives: workers, requesters, and the system itself. There are many surprising points mentioned in the paper. For example, the division-and-conquer strategy of a task can manipulate workers’ will because each worker cannot see many contexts of the task they work on. In some cases, this can prevent workers leak the sensitive information from the task. For example, if we only allow each worker see three digits number and they cannot infer that they are actually working on the credit card information. However, as mentioned in the paper, people can help the government perform surveillance tasks that against workers’ will. In addition, I’m surprised to know how smart people can utilize the crowdsourcing platform. One example is to use the crowdsourcing platform to manipulate the political views. Another example is that workers can be hired and work collaboratively to manipulate certain task results which hurt their employer’s competitors. Another important issue is also related to the exploitation of the crowdsourcing system. For example, people can organize the workers to post the fake news on the social media to manipulate the public opinions. People spend a lot of effort on detecting the fake news and thanks to this paper, I start to think about how those fake news can be massively spread over different social media platforms in such a quick fashion.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="dirty-deeds-done-dirt-cheap-a-darker-side-to-crowdsourcing"&gt;“Dirty Deeds Done Dirt Cheap: A Darker Side to Crowdsourcing”&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Harris, Christopher G. &lt;a href="http://cs.oswego.edu/~chris/papers/harris_c08.pdf"&gt;Dirty Deeds Done Dirt Cheap: A Darker Side to Crowdsourcing&lt;/a&gt;. In Privacy, security, risk and trust (passat), 2011, pp. 1314-1317. IEEE.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this paper, the author talks about the potential that the crowdsourcing system can be used for the unethical purpose. One interesting issue first posed by the paper is how to define unethical. As shown in the paper, different demographic group views the unethical behavior differently. This poses the challenges of policing ethical behavior on the internet. However, I’m very interested to know more how the author might want to model the different unethical behaviors. Another interesting point made by the author is the mention of social engineering. The motivation for social engineering mentioned in the paper is financial gains and identity theft. However, I think this is a big issue especially if we consider the government can utilize the crowdsourcing platform to perform surveillance against the nation’s citizens. This matters people’s privacy and human rights. That leads to another question: How can we prevent the crowdsourcing platform being used to hurt people’s rights. One suggestion made in the paper is by law by stating certain crowdsourcing behavior illegal. However, I think the platform needs to ban out certain tasks to be performed and put those forbidden tasks in the user’s agreement. At the same time, certain supervising needs to perform by the staff members from the platform.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Dec/30/crowdsourcing-readings/"&gt;Back To Top&lt;/a&gt;&lt;/p&gt;</content><category term="Crowdsourcing &amp; Human Computation"></category><category term="crowdsourcing"></category><category term="papers"></category></entry><entry><title>Introduction to Conditional Random Fields</title><link href="https://zhu45.org/posts/2017/Sep/22/introduction-to-conditional-random-fields/" rel="alternate"></link><published>2017-09-22T10:20:00+08:00</published><updated>2017-09-22T10:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-09-22:/posts/2017/Sep/22/introduction-to-conditional-random-fields/</id><summary type="html">&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This is a repost of the &lt;a href="http://blog.echen.me/"&gt;Edwin Chen&lt;/a&gt;‘s blog: &lt;a href="http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/"&gt;Introduction to Conditional Random Fields&lt;/a&gt; in year 2012.
I do this based on three purposes: 1. Bookmark for my course project reference 2. Fix the math rendering issue happened to the original post 3. Small tweaks to the layout …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This is a repost of the &lt;a href="http://blog.echen.me/"&gt;Edwin Chen&lt;/a&gt;‘s blog: &lt;a href="http://blog.echen.me/2012/01/03/introduction-to-conditional-random-fields/"&gt;Introduction to Conditional Random Fields&lt;/a&gt; in year 2012.
I do this based on three purposes: 1. Bookmark for my course project reference 2. Fix the math rendering issue happened to the original post 3. Small tweaks to the layout of math and notations to easy my understanding.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Imagine you have a sequence of snapshots from a day in Justin Bieber’s life, and you want to label each image with the activity it represents (eating, sleeping, driving, etc.). How can you do this?&lt;/p&gt;
&lt;p&gt;One way is to ignore the sequential nature of the snapshots, and build a per-image classifier. For example, given a month’s worth of labeled snapshots, you might learn that dark images taken at 6am tend to be about sleeping, images with lots of bright colors tend to be about dancing, images of cars are about driving, and so on.&lt;/p&gt;
&lt;p&gt;By ignoring this sequential aspect, however, you lose a lot of information. For example, what happens if you see a close-up picture of a mouth – is it about singing or eating? If you know that the previous image is a picture of Justin Bieber eating or cooking, then it’s more likely this picture is about eating; if, however, the previous image contains Justin Bieber singing or dancing, then this one probably shows him singing as well.&lt;/p&gt;
&lt;p&gt;Thus, to increase the accuracy of our labeler, we should incorporate the labels of nearby photos, and this is precisely what a conditional random field does.&lt;/p&gt;
&lt;h2 id="part-of-speech-tagging"&gt;Part-of-Speech Tagging&lt;/h2&gt;
&lt;p&gt;Let’s go into some more detail, using the more common example of part-of-speech tagging.&lt;/p&gt;
&lt;p&gt;In POS tagging, the goal is to label a sentence (a sequence of words or tokens) with tags like ADJECTIVE, NOUN, PREPOSITION, VERB, ADVERB, ARTICLE.&lt;/p&gt;
&lt;p&gt;For example, given the sentence “Bob drank coffee at Starbucks”, the labeling might be “Bob (NOUN) drank (VERB) coffee (NOUN) at (PREPOSITION) Starbucks (NOUN)”.&lt;/p&gt;
&lt;p&gt;So let’s build a conditional random field to label sentences with their parts of speech. Just like any classifier, we’ll first need to decide on a set of feature functions &lt;span class="math"&gt;\(f_i\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="feature-functions-in-a-crf"&gt;Feature Functions in a CRF&lt;/h2&gt;
&lt;p&gt;In a CRF, each feature function is a function that takes in :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a sentence s&lt;/li&gt;
&lt;li&gt;the position i of a word in the sentence&lt;/li&gt;
&lt;li&gt;the label &lt;span class="math"&gt;\(l_i\)&lt;/span&gt; of the current word&lt;/li&gt;
&lt;li&gt;the label &lt;span class="math"&gt;\(l_{i-1}\)&lt;/span&gt; of the previous word&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;as input and outputs a real-valued number (though the numbers are often just either 0 or 1).&lt;/p&gt;
&lt;p&gt;(Note: by restricting our features to depend on only the current and previous labels, rather than arbitrary labels throughout the sentence, I’m actually building the special case of a linear-chain CRF. For simplicity, I’m going to ignore general CRFs in this post.)&lt;/p&gt;
&lt;p&gt;For example, one possible feature function could measure how much we suspect that the current word should be labeled as an adjective given that the previous word is “very”.&lt;/p&gt;
&lt;h2 id="features-to-probabilities"&gt;Features to Probabilities&lt;/h2&gt;
&lt;p&gt;Next, assign each feature function &lt;span class="math"&gt;\(f_j\)&lt;/span&gt; a weight &lt;span class="math"&gt;\(\lambda_j\)&lt;/span&gt; (I’ll talk below about how to learn these weights from the data). Given a sentence s, we can now score a labeling l of s by adding up the weighted features over all words in the sentence:&lt;/p&gt;
&lt;div class="math"&gt;$$
\text{score}(l | s) = \sum_{j = 1}^m \sum_{i = 1}^n \lambda_j f_j(s, i, l_i, l_{i-1})
$$&lt;/div&gt;
&lt;p&gt;(The first sum runs over each feature function &lt;span class="math"&gt;\(j\)&lt;/span&gt;, and the inner sum runs over each position &lt;span class="math"&gt;\(i\)&lt;/span&gt; of the sentence.)&lt;/p&gt;
&lt;p&gt;Finally, we can transform these scores into probabilities &lt;span class="math"&gt;\(p(l | s)\)&lt;/span&gt; between 0 and 1 by exponentiating and normalizing:&lt;/p&gt;
&lt;div class="math"&gt;$$
p(l | s) = \frac{exp[\text{score}(l|s)]}{\sum_{l’} exp[\text{score}(l’|s)]} = \frac{exp[\sum_{j = 1}^m \sum_{i = 1}^n \lambda_j f_j(s, i, l_i, l_{i-1})]}{\sum_{l’} exp[\sum_{j = 1}^m \sum_{i = 1}^n \lambda_j f_j(s, i, l’_i, l’_{i-1})]}
$$&lt;/div&gt;
&lt;h2 id="example-feature-functions"&gt;Example Feature Functions&lt;/h2&gt;
&lt;p&gt;So what do these feature functions look like? Examples of POS tagging features could include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(f_1(s, i, l_i, l_{i-1}) = 1\)&lt;/span&gt; if &lt;span class="math"&gt;\(l_i =\)&lt;/span&gt; ADVERB and the &lt;span class="math"&gt;\(i\)&lt;/span&gt;th word ends in “-ly”; 0 otherwise.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the weight &lt;span class="math"&gt;\(\lambda_1\)&lt;/span&gt; associated with this feature is large and positive, then this feature is essentially saying that we prefer labelings where words ending in -ly get labeled as ADVERB.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(f_2(s, i, l_i, l_{i-1}) = 1\)&lt;/span&gt; if &lt;span class="math"&gt;\(i = 1\)&lt;/span&gt;, &lt;span class="math"&gt;\(l_i =\)&lt;/span&gt; VERB, and the sentence ends in a question mark; 0 otherwise.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Again, if the weight &lt;span class="math"&gt;\(\lambda_2\)&lt;/span&gt; associated with this feature is large and positive, then labelings that assign VERB to the first word in a question (e.g., “Is this a sentence beginning with a verb?”) are preferred.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(f_3(s, i, l_i, l_{i-1}) = 1\)&lt;/span&gt; if &lt;span class="math"&gt;\(l_{i-1} =\)&lt;/span&gt; ADJECTIVE and &lt;span class="math"&gt;\(l_i =\)&lt;/span&gt; NOUN; 0 otherwise.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Again, a positive weight for this feature means that adjectives tend to be followed by nouns.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(f_4(s, i, l_i, l_{i-1}) = 1\)&lt;/span&gt; if &lt;span class="math"&gt;\(l_{i-1} =\)&lt;/span&gt; PREPOSITION and &lt;span class="math"&gt;\(l_i =\)&lt;/span&gt; PREPOSITION.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A negative weight &lt;span class="math"&gt;\(\lambda_4\)&lt;/span&gt; for this function would mean that prepositions don’t tend to follow prepositions, so we should avoid labelings where this happens.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that’s it! To sum up: to build a conditional random field, you just define a bunch of feature functions (which can depend on the entire sentence, a current position, and nearby labels), assign them weights, and add them all together, transforming at the end to a probability if necessary.&lt;/p&gt;
&lt;p&gt;Now let’s step back and compare CRFs to some other common machine learning techniques.&lt;/p&gt;
&lt;h2 id="smells-like-logistic-regression"&gt;Smells like Logistic Regression…&lt;/h2&gt;
&lt;p&gt;The form of the CRF probabilities &lt;span class="math"&gt;\(p(l | s) = \frac{exp[\sum_{j = 1}^m \sum_{i = 1}^n f_j(s, i, l_i, l_{i-1})]}{\sum_{l’} exp[\sum_{j = 1}^m \sum_{i = 1}^n f_j(s, i, l’_i, l’_{i-1})]}\)&lt;/span&gt; might look familiar.&lt;/p&gt;
&lt;p&gt;That’s because CRFs are indeed basically the sequential version of logistic regression: whereas logistic regression is a log-linear model for classification, CRFs are a log-linear model for sequential labels.&lt;/p&gt;
&lt;h2 id="looks-like-hmms"&gt;Looks like HMMs…&lt;/h2&gt;
&lt;p&gt;Recall that Hidden Markov Models are another model for part-of-speech tagging (and sequential labeling in general). Whereas CRFs throw any bunch of functions together to get a label score, HMMs take a generative approach to labeling, defining&lt;/p&gt;
&lt;div class="math"&gt;$$
p(l,s) = p(l_1) \prod_i p(l_i | l_{i-1}) p(w_i | l_i)
$$&lt;/div&gt;
&lt;p&gt;where&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(p(l_i | l_{i-1})\)&lt;/span&gt; are transition probabilities (e.g., the probability that a preposition is followed by a noun);&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(p(w_i | l_i)\)&lt;/span&gt; are emission probabilities (e.g., the probability that a noun emits the word “dad”). Notice &lt;span class="math"&gt;\(w_i\)&lt;/span&gt; means the word &lt;span class="math"&gt;\(i\)&lt;/span&gt; in a sentence.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So how do HMMs compare to CRFs? CRFs are more powerful – they can model everything HMMs can and more. One way of seeing this is as follows.&lt;/p&gt;
&lt;p&gt;Note that the log of the HMM probability is &lt;span class="math"&gt;\(\log p(l,s) = \log p(l_0) + \sum_i \log p(l_i | l_{i-1}) + \sum_i \log p(w_i | l_i)\)&lt;/span&gt;. This has exactly the log-linear form of a CRF if we consider these log-probabilities to be the weights associated to binary transition and emission indicator features.&lt;/p&gt;
&lt;p&gt;That is, we can build a CRF equivalent to any HMM by…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For each HMM transition probability &lt;span class="math"&gt;\(p(l_i = y | l_{i-1} = x)\)&lt;/span&gt;, define a set of CRF transition features of the form &lt;span class="math"&gt;\(f_{x,y}(s, i, l_i, l_{i-1}) = 1\)&lt;/span&gt; if &lt;span class="math"&gt;\(l_i = y\)&lt;/span&gt; and &lt;span class="math"&gt;\(l_{i-1} = x\)&lt;/span&gt;. Give each feature a weight of &lt;span class="math"&gt;\(w_{x,y} = \log p(l_i = y | l_{i-1} = x)\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Similarly, for each HMM emission probability &lt;span class="math"&gt;\(p(w_i = z | l_{i} = x)\)&lt;/span&gt;, define a set of CRF emission features of the form &lt;span class="math"&gt;\(g_{x,y}(s, i, l_i, l_{i-1}) = 1\)&lt;/span&gt; if &lt;span class="math"&gt;\(w_i = z\)&lt;/span&gt; and &lt;span class="math"&gt;\(l_i = x\)&lt;/span&gt;. Give each feature a weight of &lt;span class="math"&gt;\(w_{x,z} = \log p(w_i = z | l_i = x)\)&lt;/span&gt;. Again, &lt;span class="math"&gt;\(w_i\)&lt;/span&gt; represents the word &lt;span class="math"&gt;\(i\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thus, the score &lt;span class="math"&gt;\(p(l|s)\)&lt;/span&gt; computed by a CRF using these feature functions is precisely proportional to the score computed by the associated HMM, and so every HMM is equivalent to some CRF.&lt;/p&gt;
&lt;p&gt;However, CRFs can model a much richer set of label distributions as well, for two main reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CRFs can define a much larger set of features.&lt;/strong&gt; Whereas HMMs are necessarily local in nature (because they’re constrained to binary transition and emission feature functions, which force each word to depend only on the current label and each label to depend only on the previous label), CRFs can use more global features. For example, one of the features in our POS tagger above increased the probability of labelings that tagged the first word of a sentence as a VERB if the end of the sentence contained a question mark.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CRFs can have arbitrary weights.&lt;/strong&gt; Whereas the probabilities of an HMM must satisfy certain constraints (e.g., &lt;span class="math"&gt;\(0 &amp;lt;= p(w_i | l_i) &amp;lt;= 1, \sum_w p(w_i = w | l_1) = 1)\)&lt;/span&gt;, the weights of a CRF are unrestricted (e.g., &lt;span class="math"&gt;\(\log p(w_i | l_i)\)&lt;/span&gt; can be anything it wants).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="learning-weights"&gt;Learning Weights&lt;/h2&gt;
&lt;p&gt;Let’s go back to the question of how to learn the feature weights in a CRF. One way is (surprise) to use gradient ascent.&lt;/p&gt;
&lt;p&gt;Assume we have a bunch of training examples (sentences and associated part-of-speech labels). Randomly initialize the weights of our CRF model. To shift these randomly initialized weights to the correct ones, for each training example…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Go through each feature function &lt;span class="math"&gt;\(f_i\)&lt;/span&gt;, and calculate the gradient of the log probability of the training example with respect to &lt;span class="math"&gt;\(\lambda_i\)&lt;/span&gt;: &lt;span class="math"&gt;\(\frac{\partial}{\partial w_j} \log p(l | s) = \sum_{j = 1}^m f_i(s, j, l_j, l_{j-1}) - \sum_{l’} p(l’ | s) \sum_{j = 1}^m f_i(s, j, l’_j, l’_{j-1})\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Note that the first term in the gradient is the contribution of feature &lt;span class="math"&gt;\(f_i\)&lt;/span&gt; under the true label, and the second term in the gradient is the expected contribution of feature &lt;span class="math"&gt;\(f_i\)&lt;/span&gt; under the current model. This is exactly the form you’d expect gradient ascent to take.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Move &lt;span class="math"&gt;\(\lambda_i\)&lt;/span&gt; in the direction of the gradient: &lt;span class="math"&gt;\(\lambda_i = \lambda_i + \alpha [\sum_{j = 1}^m f_i(s, j, l_j, l_{j-1}) - \sum_{l’} p(l’ | s) \sum_{j = 1}^m f_i(s, j, l’_j, l’_{j-1})]\)&lt;/span&gt; where &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; is some learning rate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repeat the previous steps until some stopping condition is reached (e.g., the updates fall below some threshold).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, every step takes the difference between what we want the model to learn and the model’s current state, and moves &lt;span class="math"&gt;\(\lambda_i\)&lt;/span&gt; in the direction of this difference.&lt;/p&gt;
&lt;h2 id="finding-the-optimal-labeling"&gt;Finding the Optimal Labeling&lt;/h2&gt;
&lt;p&gt;Suppose we’ve trained our CRF model, and now a new sentence comes in. How do we do label it?&lt;/p&gt;
&lt;p&gt;The naive way is to calculate &lt;span class="math"&gt;\(p(l | s)\)&lt;/span&gt; for every possible labeling l, and then choose the label that maximizes this probability. However, since there are &lt;span class="math"&gt;\(k^m\)&lt;/span&gt; possible labels for a tag set of size k and a sentence of length m, this approach would have to check an exponential number of labels.&lt;/p&gt;
&lt;p&gt;A better way is to realize that (linear-chain) CRFs satisfy an optimal substructure property that allows us to use a (polynomial-time) dynamic programming algorithm to find the optimal label, similar to the Viterbi algorithm for HMMs.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="09"></category><category term="natural language processing"></category><category term="machine learning"></category></entry><entry><title>Watching log of CMU Database Systems course</title><link href="https://zhu45.org/posts/2017/Sep/08/watching-log-of-cmu-database-systems-course/" rel="alternate"></link><published>2017-09-08T12:30:00+08:00</published><updated>2017-09-08T12:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-09-08:/posts/2017/Sep/08/watching-log-of-cmu-database-systems-course/</id><summary type="html">&lt;p&gt;log book for CMU 15-445/15-645 Database Systems Fall 2017 course&lt;/p&gt;</summary><content type="html">&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;There is a hobby I always want to develop but never gets into practice: watch lecture videos while I eat. The
reason because lecture videos are mostly not fun especially when the content of the video is entirely new to you.
However, this semester I want to actually start developing this habbit partly because I’m missing system side of computer science.
I miss the database knowledge I have picked up in the past three years and I don’t want to lose the touch
in this field. So, I think why not start to watch database lecture videoes for fun when I eat? That leads to this post.&lt;/p&gt;
&lt;p&gt;This post is a log of cool points I like when I watch &lt;a href="https://www.youtube.com/channel/UCHnBsf2rH-K7pn09rb3qvkA"&gt;CMU Database Group Database Systems lecture video&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="log"&gt;Log&lt;/h2&gt;
&lt;p&gt;— 09/07/2017 UPDATE —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There are bunch of data models besides relational model: relational,
key/value, graph, document, column-family, array/matrix, hierarchical, network&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Thanks to Prof.Andy Pavlo, I finally understand the difference between
relational algebra and relational calculus in terms of their purpose:&lt;/p&gt;
&lt;p&gt;When we talk about using data manipulation language (DML) to store
and retrieve information from a database, there are two categories:
procedural and non-procedural, which corresponds to relational algebra
and relational calculus respectively. For procedural language, the query specifies
the (high-level) strategy the DBMS should use to find the desired result. For
non-procedural lanaguages, the query specifies only what data is wanted and not how to
find it. In fact, SQL is derived from relational calculus. In other words, 
relational calculus is used when we try to come up with a different 
query language to replace SQL.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The fundamental operators in relational algebra need to be implemented
in the database system in order to manipulate tuples: &lt;span class="math"&gt;\(\sigma \text{(select)}, \pi \text{(projection)}, \cup \text{(union)},
\cap \text{(intersection)}, - \text{(difference)}, \times \text{(product)}, \bowtie \text{(join)}\)&lt;/span&gt;. &lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;— 11/14/2018 UPDATE —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Lock vs. Latch in database context: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lock is a high-level primitive on a logical component of a database: a lock on a database, a lock on a table, a lock on a record&lt;/li&gt;
&lt;li&gt;Latch is the lock from OS perspective (a low-level primitive that works on the data structure): a latch on the page table,
  a latch on a index page&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Database"></category><category term="database"></category></entry><entry><title>MAW Chapter 8: Disjoint set</title><link href="https://zhu45.org/posts/2017/Aug/29/maw-chapter-8-disjoint-set/" rel="alternate"></link><published>2017-08-29T01:12:00+08:00</published><updated>2017-08-29T01:12:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-08-29:/posts/2017/Aug/29/maw-chapter-8-disjoint-set/</id><summary type="html">&lt;p&gt;disjoint set Union-Find algorithm&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Disjoint Set&lt;/em&gt; ADT is an efficient data structure to solve the equivalence problems. It has wide applications:
Kruskal’s minimum spanning tree algorithm, Least common ancestor, compiling equivalence statements in Fortran,
Matlab’s &lt;code&gt;bwlabel()&lt;/code&gt; function in image processing, and so on. In this post, I’ll walk through this data structure
in order to have the better preparation for the graph algorithms in the following chapter of MAW.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#equivalence-relations"&gt;Equivalence relations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-dynamic-equivalence-problem"&gt;The dynamic equivalence problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quick-find"&gt;Quick-find&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#quick-union"&gt;Quick-union&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#improvements"&gt;Improvements&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#smart-union-weighted-quick-union"&gt;Smart union (weighted quick-union)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#path-compressionn"&gt;Path compressionn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#remarks"&gt;Remarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#links-to-resources"&gt;Links to resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The implementation of the quick-find, quick-union, smart-union with path compression in C can be seen &lt;a href="https://github.com/xxks-kkk/algo/tree/master/union-find"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/xxks-kkk/shuati/blob/d3d53e7b143478e8a2be123cedcc21bad879307b/leetcode/200-NumberOfIslands/numberOfIslands.cc#L29-L81"&gt;an application to solve problem in C++&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="equivalence-relations"&gt;Equivalence relations&lt;/h2&gt;
&lt;p&gt;In order to better describe the dynamic equivalence problem, we need to first talk about the concept &lt;em&gt;equivalence relation&lt;/em&gt;.
A &lt;strong&gt;relation&lt;/strong&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; is defined on a set &lt;span class="math"&gt;\(S\)&lt;/span&gt; if for every pair of elements &lt;span class="math"&gt;\((a,b)\)&lt;/span&gt;, &lt;span class="math"&gt;\(a,b \in S\)&lt;/span&gt;, &lt;span class="math"&gt;\(a\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(b\)&lt;/span&gt; is either true or false.
If &lt;span class="math"&gt;\(a\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(b\)&lt;/span&gt; is true, then we say that &lt;span class="math"&gt;\(a\)&lt;/span&gt; is related to &lt;span class="math"&gt;\(b\)&lt;/span&gt;. An &lt;strong&gt;equivalence relation&lt;/strong&gt; is a relation &lt;span class="math"&gt;\(R\)&lt;/span&gt; that satisfies three properties:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;(&lt;em&gt;Reflective&lt;/em&gt;) &lt;span class="math"&gt;\(a\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(a\)&lt;/span&gt;, for all &lt;span class="math"&gt;\(a \in S\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;(&lt;em&gt;Symmetric&lt;/em&gt;) &lt;span class="math"&gt;\(a\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(b\)&lt;/span&gt; iff &lt;span class="math"&gt;\(b\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(a\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;(&lt;em&gt;Transitive&lt;/em&gt;) &lt;span class="math"&gt;\(a\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(b\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(c\)&lt;/span&gt; implies that &lt;span class="math"&gt;\(a\)&lt;/span&gt; &lt;span class="math"&gt;\(R\)&lt;/span&gt; &lt;span class="math"&gt;\(c\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Usually, we use &lt;span class="math"&gt;\(\sim\)&lt;/span&gt; to denote equivalence relation. Let’s consider several examples:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;span class="math"&gt;\(\le\)&lt;/span&gt; relationship is NOT an equivalence relationship. Although it is reflexive (i.e., &lt;span class="math"&gt;\(a \le a\)&lt;/span&gt;) and transitive (i.e., &lt;span class="math"&gt;\(a \le b\)&lt;/span&gt; and &lt;span class="math"&gt;\(b \le c\)&lt;/span&gt; implies &lt;span class="math"&gt;\(a \le c\)&lt;/span&gt;),
it is not symmetric, since &lt;span class="math"&gt;\(a \le  b\)&lt;/span&gt; does not imply &lt;span class="math"&gt;\(b \le a\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Electrical connectivity, where all connections are by metal wires, is an equivalence relation. The relation is clearly reflexive, as any component is connected to itself.
If &lt;span class="math"&gt;\(a\)&lt;/span&gt; is electrically connected to &lt;span class="math"&gt;\(b\)&lt;/span&gt;, then &lt;span class="math"&gt;\(b\)&lt;/span&gt; must be electrically connected to &lt;span class="math"&gt;\(a\)&lt;/span&gt;, so the relation is symmetric. Finally, if &lt;span class="math"&gt;\(a\)&lt;/span&gt; is connected to &lt;span class="math"&gt;\(b\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt; is connected
to &lt;span class="math"&gt;\(c\)&lt;/span&gt;, then &lt;span class="math"&gt;\(a\)&lt;/span&gt; is connected to &lt;span class="math"&gt;\(c\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two cities are related if they are in the same country. This is an equivalence relation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Suppose town &lt;span class="math"&gt;\(a\)&lt;/span&gt; is related to &lt;span class="math"&gt;\(b\)&lt;/span&gt; if it is possible to travel from &lt;span class="math"&gt;\(a\)&lt;/span&gt; to &lt;span class="math"&gt;\(b\)&lt;/span&gt; by taking roads. This relation is an equivalence relation if all the roads are two-way.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We need to define another term &lt;em&gt;equivalence class&lt;/em&gt; in order to talk about dynamic equivalence problem. Suppose we are given a set of elements that have the equivalence
relation defined over (i.e. for a set &lt;span class="math"&gt;\(\{a_1,a_2,a_3\}\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(a_1 \sim a_2\)&lt;/span&gt;), the &lt;strong&gt;equivalence class&lt;/strong&gt; of an element &lt;span class="math"&gt;\(a \in S\)&lt;/span&gt; is the subset of &lt;span class="math"&gt;\(S\)&lt;/span&gt; that contains all the 
elements that are related to &lt;span class="math"&gt;\(a\)&lt;/span&gt;. Notice that the equivalence classes form a partition of &lt;span class="math"&gt;\(S\)&lt;/span&gt;: every member of &lt;span class="math"&gt;\(S\)&lt;/span&gt; appears in exactly one equivalence class. &lt;/p&gt;
&lt;h2 id="the-dynamic-equivalence-problem"&gt;The dynamic equivalence problem&lt;/h2&gt;
&lt;p&gt;The dynamic equivalence problem essentially is about supporting two operations on a set of elements where the equivalence relation is defined over:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;find&lt;/strong&gt;, which returns the name of the set (i.e., the equivalence class) containing a given element.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;union&lt;/strong&gt;, which merges the two equivalence classes containing &lt;span class="math"&gt;\(a\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt; into a new equivalence class. From a set point of view, the result of union
is to create a new set &lt;span class="math"&gt;\(S_k = S_i \cup S_j\)&lt;/span&gt;, destroying the originals and preserving the disjointness of all the sets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can model the problem like the following: the input is initally a collection of &lt;span class="math"&gt;\(N\)&lt;/span&gt; sets, each with one element. This initial representation is that all
relations(except reflexive relations) are false. Each set has a different element, so that &lt;span class="math"&gt;\(S_i \cap S_j = \emptyset\)&lt;/span&gt;; this makes the sets disjoint. In addition, 
since we only care about the knowledge of the elements’ locations not values, we can assume that all the elements have been numbered sequentially from &lt;span class="math"&gt;\(1\)&lt;/span&gt; to &lt;span class="math"&gt;\(N\)&lt;/span&gt;.
Thus, we have &lt;span class="math"&gt;\(S_i = \{i\}\)&lt;/span&gt; for &lt;span class="math"&gt;\(i = 1\)&lt;/span&gt; through &lt;span class="math"&gt;\(N\)&lt;/span&gt;. At last, we don’t care what value returned by &lt;em&gt;find&lt;/em&gt; operation as long as &lt;code&gt;find(a) = find(b)&lt;/code&gt; iff &lt;span class="math"&gt;\(a\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt;
are in the same set.&lt;/p&gt;
&lt;p&gt;Now, let’s take a look at an example. Suppose we have a set of &lt;span class="math"&gt;\(10\)&lt;/span&gt; elements: &lt;span class="math"&gt;\(\{0,1,2,3,4,5,6,7,8,9\}\)&lt;/span&gt; and we perform the following union operations: 
&lt;span class="math"&gt;\(1 - 2, 3-4, 5-6, 7-8, 7-9, 2-8, 0-5, 1-9\)&lt;/span&gt;. Then, we have three connected components (i.e. maximal set of objects that are mutually connected): 
&lt;span class="math"&gt;\(\{0,5,6\}, \{3,4\}, \{1,2,7,8,9\}\)&lt;/span&gt;. &lt;code&gt;find(5)&lt;/code&gt; should return the same value as &lt;code&gt;find(6)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="quick-find"&gt;Quick-find&lt;/h2&gt;
&lt;p&gt;The first approach to solve the problem is called quick-find, which ensures that the &lt;code&gt;find&lt;/code&gt; instruction can be executed in constant worst-case time.
For the &lt;code&gt;find&lt;/code&gt; operation to be fast, we could maintain, in an array, the name of the equivalence class for each element. Then &lt;code&gt;find&lt;/code&gt; is just a 
simple &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; lookup:&lt;/p&gt;
&lt;p&gt;&lt;img alt="find operation example in quick-find" class="img-responsive" src="https://zhu45.org/images/quick-find-find.png"/&gt;&lt;/p&gt;
&lt;p&gt;In the above example, &lt;code&gt;find(0)&lt;/code&gt; gives &lt;span class="math"&gt;\(0\)&lt;/span&gt;; &lt;code&gt;find(1)&lt;/code&gt; gives &lt;span class="math"&gt;\(1\)&lt;/span&gt;; &lt;code&gt;find(5)&lt;/code&gt; gives &lt;span class="math"&gt;\(0\)&lt;/span&gt;. Thus, we know that &lt;span class="math"&gt;\(0 \sim 5\)&lt;/span&gt;, &lt;span class="math"&gt;\(0 \nsim 1\)&lt;/span&gt;, and &lt;span class="math"&gt;\(1 \nsim 5\)&lt;/span&gt;. 
For the &lt;code&gt;union(a,b)&lt;/code&gt; operation, suppose that &lt;span class="math"&gt;\(a\)&lt;/span&gt; is in equivalence class &lt;span class="math"&gt;\(i\)&lt;/span&gt; and &lt;span class="math"&gt;\(b\)&lt;/span&gt; is in equivalence class &lt;span class="math"&gt;\(j\)&lt;/span&gt;. Then we scan down the array, 
changing all &lt;span class="math"&gt;\(i\)&lt;/span&gt;‘s to &lt;span class="math"&gt;\(j\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="union operation example in quick-find" class="img-responsive" src="https://zhu45.org/images/quick-find-union.png"/&gt;&lt;/p&gt;
&lt;p&gt;In the above example, when do &lt;code&gt;union(6,1)&lt;/code&gt;, we need to change all entries in the equivalence class of &lt;span class="math"&gt;\(6\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(0,5,6\)&lt;/span&gt;) into &lt;span class="math"&gt;\(1\)&lt;/span&gt;‘s. As you can
see, the number of array acesses for union operation is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;. Thus, a sequence of &lt;span class="math"&gt;\(N-1\)&lt;/span&gt; &lt;code&gt;union&lt;/code&gt; (the maximum, then everything is in one set) would
take &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt; time.&lt;/p&gt;
&lt;h2 id="quick-union"&gt;Quick-union&lt;/h2&gt;
&lt;p&gt;The second approach to solve the problem is to ensure that the &lt;code&gt;union&lt;/code&gt; instruction can be executed in constant worst-case time, which is called “quick-union”.
One thing to note is that both &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;union&lt;/code&gt; cannot be done simultaneously in constant worst-case time. Recall that the problem doesn’t 
require that a &lt;code&gt;find&lt;/code&gt; operation return any specific name as long as &lt;code&gt;find&lt;/code&gt; on the elements in the same connected component returns the same value. Thus,
we can use a tree to represent each component becase each element in a tree has the same root. Thus, the root can be used to name the set. The structure 
looks like below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="quick-union structure" class="img-responsive" src="https://zhu45.org/images/quick-union.png"/&gt;&lt;/p&gt;
&lt;p&gt;Since only the name of the parent is required, we can assume that this tree is stored implicitly in an array: each entry &lt;span class="math"&gt;\(\text{id}[i]\)&lt;/span&gt; in the array represents the 
parent of element &lt;span class="math"&gt;\(i\)&lt;/span&gt;. If &lt;span class="math"&gt;\(i\)&lt;/span&gt; is the root, then &lt;span class="math"&gt;\(\text{id}[i] = i\)&lt;/span&gt;. A &lt;code&gt;find(X)&lt;/code&gt; on element &lt;span class="math"&gt;\(X\)&lt;/span&gt; is performed by returning the root of the tree containing &lt;span class="math"&gt;\(X\)&lt;/span&gt;. The time 
to perform this operation depending on the depth of the tree that represents the set containing &lt;span class="math"&gt;\(X\)&lt;/span&gt;, which is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; in the worst case because of the possiblity of creating
a tree of depth &lt;span class="math"&gt;\(N-1\)&lt;/span&gt;. &lt;code&gt;union(p,q)&lt;/code&gt; can be done by change the root of tree containing &lt;span class="math"&gt;\(p\)&lt;/span&gt; into the value of root containing &lt;span class="math"&gt;\(q\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="quick-union union operation" class="img-responsive" src="https://zhu45.org/images/quick-union-union.png"/&gt;&lt;/p&gt;
&lt;p&gt;Changing the root value step in &lt;code&gt;union(p,q)&lt;/code&gt; is &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt;. However, since we need to find the root of &lt;span class="math"&gt;\(p\)&lt;/span&gt; and &lt;span class="math"&gt;\(q\)&lt;/span&gt; respectively, which takes &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; in the worst case.
Thus, the &lt;code&gt;union&lt;/code&gt; operation takes &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="improvements"&gt;Improvements&lt;/h2&gt;
&lt;p&gt;There are two major improvements we can do with our quick-union: smart-union works on &lt;code&gt;union&lt;/code&gt; operation and path compression works on &lt;code&gt;find&lt;/code&gt; operation. Their goal is
to make the tree of each set shallow, which can reduce the time we spend on &lt;code&gt;find&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="smart-union-weighted-quick-union"&gt;Smart union (weighted quick-union)&lt;/h3&gt;
&lt;p&gt;Smart union is a modification to quick-union that avoid tall trees. We keep track of the size (i.e., number of objects) of each tree and always to link the root of smaller
tree to root of larger tree, breaking ties by any method. This approach is called &lt;strong&gt;union-by-size&lt;/strong&gt;. In quick-union, we may make the larger tree a subtree of the smaller tree, which
increase the depth of the new tree, which increase the &lt;code&gt;find&lt;/code&gt; cost. The following picture demonstrates this point:&lt;/p&gt;
&lt;p&gt;&lt;img alt="union-by-size motivation" class="img-responsive" src="https://zhu45.org/images/union-by-size.png"/&gt;&lt;/p&gt;
&lt;p&gt;Another approach is called &lt;strong&gt;union-by-height&lt;/strong&gt;, which tracks the height, instead of the size, of each tree and perform &lt;code&gt;union&lt;/code&gt; by making the shallow tree a subtree of the deeper tree.
Since the height of a tree increases only when two equally deep trees are joined (and then the height goes up by one). Thus, union-by-height is a trivial modification of union-by-size.&lt;/p&gt;
&lt;p&gt;To find the running time of &lt;code&gt;find&lt;/code&gt; and &lt;code&gt;union&lt;/code&gt;, we need to find out the depth of any node &lt;span class="math"&gt;\(X\)&lt;/span&gt;, which in this case is at most &lt;span class="math"&gt;\(\log N\)&lt;/span&gt;. The proof is simple: when the depth of &lt;span class="math"&gt;\(X\)&lt;/span&gt; increases, the
size of tree is at least doubled (i.e., join two equal-size trees). Since there are at maximum &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes for a tree, the size of trees doubled at least &lt;span class="math"&gt;\(\log N\)&lt;/span&gt; times. Thus, the depth of
any node is at most &lt;span class="math"&gt;\(\log N\)&lt;/span&gt;. With this claim, we have running time for &lt;code&gt;find&lt;/code&gt; is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; and running time for &lt;code&gt;union&lt;/code&gt; is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; as well. &lt;/p&gt;
&lt;h3 id="path-compressionn"&gt;Path compressionn&lt;/h3&gt;
&lt;p&gt;Path compression is performed during a &lt;code&gt;find&lt;/code&gt; operation and is independent of the strategy used to perform &lt;code&gt;union&lt;/code&gt;. The effect of path compression is that every node on the path from &lt;span class="math"&gt;\(X\)&lt;/span&gt;
to the root has its parent changed to the root. For example, suppose we call &lt;code&gt;find(9)&lt;/code&gt; for the following tree representation of our disjoint set:&lt;/p&gt;
&lt;p&gt;&lt;img alt="path compression example start state" class="img-responsive" src="https://zhu45.org/images/path-compression-1.png"/&gt;&lt;/p&gt;
&lt;p&gt;Then the following picture shows the end state of our tree after calling &lt;code&gt;find(9)&lt;/code&gt;. As you can see, on the path from &lt;span class="math"&gt;\(9\)&lt;/span&gt; to &lt;span class="math"&gt;\(0\)&lt;/span&gt; (root), we have &lt;span class="math"&gt;\(9, 6, 3, 1\)&lt;/span&gt;. All of them have been directly 
connected to the root after the call is done:&lt;/p&gt;
&lt;p&gt;&lt;img alt="path compression example end state" class="img-responsive" src="https://zhu45.org/images/path-compression-2.png"/&gt;&lt;/p&gt;
&lt;p&gt;This strategy may look familiar to you: we do the path compression in the hope of the fast future accesses on these nodes (i.e., &lt;span class="math"&gt;\(9,6,3,1\)&lt;/span&gt;) will pay off for the work we do now. This idea
is exactly the same as the &lt;a href="https://zhu45.org/posts/2017/Feb/13/splay-tree/"&gt;splaying&lt;/a&gt; in splay tree. &lt;/p&gt;
&lt;p&gt;When &lt;code&gt;union&lt;/code&gt; are done arbitrarily, path compression is a good idea, because there is an abundance of deep nodes and these are brought near the root by path compression. Path compression
is perfectly compatible with union-by-size, and thus both routines can be implemented at the same time. In fact, the combination of path compression and a smart union rule guarantees 
a very efficient algorithm in all cases. Path compression is not entirely compatible with union-by-height, because path compression can change the heights of the trees. We don’t want
to recompute all the heights and in this case, heights stored for each tree become estimated heights (i.e., &lt;strong&gt;ranks&lt;/strong&gt;), but in theory union-by-rank is as efficient as union-by-size.&lt;/p&gt;
&lt;p&gt;If we do analysis on smart union with path compression, the running time for any sequence of &lt;span class="math"&gt;\(M\)&lt;/span&gt; union-find operations on &lt;span class="math"&gt;\(N\)&lt;/span&gt; objects makes &lt;span class="math"&gt;\(O(N + M\log^*N)\)&lt;/span&gt; &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; accesses.&lt;/p&gt;
&lt;p&gt;The following table summarizes the running time for &lt;span class="math"&gt;\(M\)&lt;/span&gt; union-find operations on a set of &lt;span class="math"&gt;\(N\)&lt;/span&gt; objects (don’t forget we need to spend &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; to initialize disjoint sets):&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;algorithm&lt;/th&gt;
&lt;th&gt;worst-case time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;quick-find&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(MN\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quick-union&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(MN\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;smart union&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(N + M\log N\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quick union + path compression&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(N + M\log N\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;smart union + path compression&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(N + M\log^*N\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The running time for each operation for each algorithm is following:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;algorithm&lt;/th&gt;
&lt;th&gt;initialize&lt;/th&gt;
&lt;th&gt;union&lt;/th&gt;
&lt;th&gt;find&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;quick-find&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quick-union&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;smart union&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\log N\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\log N\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;quick union + path compression&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\log N\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\log N\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;smart union + path compression&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\log^*N\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(\log^*N\)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="remarks"&gt;Remarks&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://algs4.cs.princeton.edu/lectures/15UnionFind-2x2.pdf"&gt;Sedgewick slide&lt;/a&gt; offers view that may be helpful in modeling the problems using
the union-find data structure. Essentially, union-find structure addresses the “dynamic connectivity problem”:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given a set of N objects, support two operation: 1. Connect two objects. 2. Is there a path connecting the two objects?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example, given two points in a maze, we may ask “Is there a path connecting &lt;span class="math"&gt;\(p\)&lt;/span&gt; and &lt;span class="math"&gt;\(q\)&lt;/span&gt;?” Objects can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pixels in a digital photo.&lt;/li&gt;
&lt;li&gt;Computers in a network.&lt;/li&gt;
&lt;li&gt;Friends in a social network.&lt;/li&gt;
&lt;li&gt;Transistors in a computer chip.&lt;/li&gt;
&lt;li&gt;Elements in a mathematical set.&lt;/li&gt;
&lt;li&gt;Variable names in a Fortran program.&lt;/li&gt;
&lt;li&gt;Metallic sites in a composite system.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Segewick gives a list of union-find applications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Percolation.&lt;/li&gt;
&lt;li&gt;Games (Go, Hex).&lt;/li&gt;
&lt;li&gt;Dynamic connectivity.&lt;/li&gt;
&lt;li&gt;Least common ancestor.&lt;/li&gt;
&lt;li&gt;Equivalence of finite state automata.&lt;/li&gt;
&lt;li&gt;Hoshen-Kopelman algorithm in physics.&lt;/li&gt;
&lt;li&gt;Hinley-Milner polymorphic type inference.&lt;/li&gt;
&lt;li&gt;Kruskal’s minimum spanning tree algorithm.&lt;/li&gt;
&lt;li&gt;Compiling equivalence statements in Fortran.&lt;/li&gt;
&lt;li&gt;Morphological attribute openings and closings.&lt;/li&gt;
&lt;li&gt;Matlab’s bwlabel() function in image processing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;M. A. Weiss, Data Structures and Algorithm Analysis in C. (2nd ed.) Menlo Park, Calif: Addison-Wesley, 1997, ch. 8.&lt;/li&gt;
&lt;li&gt;R. Sedgewick 1946 and K. Wayne 1971, algorithms. (4th ed.) Upper Saddle River, NJ: Addison-Wesley, 2011, ch. 1, sec. 5.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\log^* N\)&lt;/span&gt; counts the number of times you have to take the &lt;span class="math"&gt;\(\log\)&lt;/span&gt; of &lt;span class="math"&gt;\(N\)&lt;/span&gt; to get one. This is also called iterated log function. For example, &lt;span class="math"&gt;\(\log^* 65536 = 4\)&lt;/span&gt; because &lt;span class="math"&gt;\(\log\log\log\log65536 = 1\)&lt;/span&gt;. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="maw"></category><category term="union-find"></category></entry><entry><title>Knapsack problem</title><link href="https://zhu45.org/posts/2017/Aug/14/knapsack-problem/" rel="alternate"></link><published>2017-08-14T16:45:00+08:00</published><updated>2017-08-14T16:45:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-08-14:/posts/2017/Aug/14/knapsack-problem/</id><summary type="html">&lt;p&gt;summarizes knapsack problem and its variations&lt;/p&gt;</summary><content type="html">&lt;p&gt;I’m studying this problem on my way from Beijing to Austin to kill some time.
This problem works pretty well for this purpose. There are three kinds of 
forms for the problem, which I’ll illustrate below. This problem is a good example
of dynamic programming paradigm.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#knapsack-problem"&gt;Knapsack problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#a-breif-revisit-to-dynamic-programming"&gt;A breif revisit to dynamic programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#0-1-knapsack-problem"&gt;0-1 knapsack problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#0-x-knapsack-problem"&gt;0-x knapsack problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#fractional-knapsack-problem"&gt;Fractional knapsack problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#links-to-resources"&gt;Links to resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="knapsack-problem"&gt;Knapsack problem&lt;/h2&gt;
&lt;p&gt;Suppose we are planning a hiking trip; and we are, therefore, interested in 
filling a knapsack with items that are considered necessary for the trip. 
There are &lt;span class="math"&gt;\(N\)&lt;/span&gt; different item types that are deemed desirable; 
these could include bottle of water, apple, orange, sandwich, and so
forth. Each item type has a given set of two attributes, namely a weight &lt;span class="math"&gt;\(W\)&lt;/span&gt; and a
value that quantifies the level of importance associated with each unit of that 
type of item. Since the knapsack has a limited weight capacity, 
the problem of interest is to figure out how to load the knapsack with a 
combination of units of the specified types of items that yields the greatest total value. &lt;/p&gt;
&lt;p&gt;A large variety of resource allocation problems can be cast in the framework of a knapsack
problem. The general idea is to think of the capacity of the knapsack as the available amount
of a resource and the item types as activities to which this resource can be allocated. Two
quick examples are the allocation of an advertising budget to the promotions of individual
products and the allocation of your effort to the preparation of final exams in different
subjects.&lt;/p&gt;
&lt;h2 id="a-breif-revisit-to-dynamic-programming"&gt;A breif revisit to dynamic programming&lt;/h2&gt;
&lt;p&gt;Dynamic programming is a algorithm design strategy when a problem can be broken
down into recurring small problems. Specifically, it is used when the solution can be
recursively described in terms of solutions to subproblems and algorithms find solutions
to subproblems and store them for later use. This is better than “brute-force methods”,
which solves the same subproblem over and over again. It is different from divide-and-conquer
paradigm in the sense that divide-and-conquer divides the problem into independent subproblems
and solve them individually, and then combine them to form the final solution. There is
no re-use of a solution to one subproblem in order to solve another subproblem, like dynamic programming.
From this perspective, dynamic programm is more like recursion + re-use &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The general steps to use dynamic programming paradigm is that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define the subproblems&lt;/li&gt;
&lt;li&gt;Define the solution to subproblems, which can be reused by other subproblems (if you think of recursion, the solution to
subproblem can be re-used by the subproblem one function call earlier).&lt;/li&gt;
&lt;li&gt;Solve the problem bottom-up from “basic cases”, building a table of solved subproblems that are used to solve larger ones&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="0-1-knapsack-problem"&gt;0-1 knapsack problem&lt;/h2&gt;
&lt;p&gt;The first type of knapsack program has the following restriction on how the item should
be picked: &lt;em&gt;items are not divisible&lt;/em&gt;. In other words, you either take an item or not.&lt;/p&gt;
&lt;p&gt;Let’s first formulate this problem mathematically. Given a knapsack with 
maximum capacity &lt;span class="math"&gt;\(W\)&lt;/span&gt;, and a set &lt;span class="math"&gt;\(S\)&lt;/span&gt; consisting of &lt;span class="math"&gt;\(n\)&lt;/span&gt; items. 
Each item &lt;span class="math"&gt;\(i\)&lt;/span&gt; has some weight &lt;span class="math"&gt;\(w_i\)&lt;/span&gt; and benefit value &lt;span class="math"&gt;\(b_i\)&lt;/span&gt;
(all &lt;span class="math"&gt;\(w_i\)&lt;/span&gt;, &lt;span class="math"&gt;\(b_i\)&lt;/span&gt; and &lt;span class="math"&gt;\(W\)&lt;/span&gt; are integer values). The problem we try to solve is 
how to pack the knapsack to achieve maximum total value of packed items? In other words,
we try to find &lt;span class="math"&gt;\(\text{max}\sum_{i \in S} b_i \text{ subject to } \sum_{i \in S} w_i \le W\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The first step in dynamic programming is to define the subproblems. In this problem, we 
can try to label the items from &lt;span class="math"&gt;\(1 \dots n\)&lt;/span&gt;, and then a subproblem is to find an optimal
solution for &lt;span class="math"&gt;\(S_i = \left\lbrace \text{items labeled }  1,2,\dots, i \right\rbrace\)&lt;/span&gt;. Once
we have a definition for the subproblem, we need to ask: can we describe the final solution
(i.e., &lt;span class="math"&gt;\(S_n\)&lt;/span&gt;) in terms of subproblems (i.e., &lt;span class="math"&gt;\(S_i\)&lt;/span&gt;)? Let’s take a look at an example:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Weight &lt;span class="math"&gt;\(w_i\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benefit &lt;span class="math"&gt;\(b_i\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Suppose &lt;span class="math"&gt;\(W = 20\)&lt;/span&gt;. Then for &lt;span class="math"&gt;\(S_4\)&lt;/span&gt;, the optimal solution is to put 
item &lt;span class="math"&gt;\(1,2,3,4\)&lt;/span&gt; into knapsack because the total weight is &lt;span class="math"&gt;\(2 + 3 + 4 + 5 = 14\)&lt;/span&gt;, which
is less than &lt;span class="math"&gt;\(20\)&lt;/span&gt; and we have the maximum benefit: &lt;span class="math"&gt;\(20\)&lt;/span&gt;. For &lt;span class="math"&gt;\(S_5\)&lt;/span&gt;, the optimal solution
is to put item &lt;span class="math"&gt;\(1,3,4,5\)&lt;/span&gt; into knapsack with the total weight &lt;span class="math"&gt;\(2 + 4 + 5 + 9 = 20\)&lt;/span&gt; and maximum
benefit &lt;span class="math"&gt;\(26\)&lt;/span&gt;. However, as you can see, the solution for &lt;span class="math"&gt;\(S_4\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(1,2,3,4\)&lt;/span&gt;) is not part
of the solution for &lt;span class="math"&gt;\(S_5\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(1,3,4,5\)&lt;/span&gt;). Thus, our definition of subproblem is not right.
Let’s refine our subproblem definition by adding another parameter &lt;span class="math"&gt;\(w\)&lt;/span&gt; that represents the
exact weight for each subset of items. Then, our subproblem is to find the best subset of 
&lt;span class="math"&gt;\(S_i\)&lt;/span&gt; that has total weight &lt;span class="math"&gt;\(w\)&lt;/span&gt;. The benefits corresponding with the best subset is denoted
as &lt;span class="math"&gt;\(B[i, w]\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The problem with the first subproblem definition is that we kind of play greedy algorithm in
the sense that we always choose the optimal solution for &lt;span class="math"&gt;\(S_i\)&lt;/span&gt; given &lt;span class="math"&gt;\(W\)&lt;/span&gt;. However, the
problem with greedy approach is that the optimal solution for &lt;span class="math"&gt;\(S_i\)&lt;/span&gt; may not be the part
of solution for &lt;span class="math"&gt;\(S_n\)&lt;/span&gt;. The refinement to that is that we allow to tweak &lt;span class="math"&gt;\(W\)&lt;/span&gt; to reflect
the number of items we are considering. This idea will become clear once we walk through
the solution to the problem. All in all, coming up a good subproblem definition is the 
key in using dynammic programming, which requires many practice.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once we have the subproblem definition, we can define our solution to the subproblem. In this 
case, our recursive formula for subproblems look like below:&lt;/p&gt;
&lt;div class="math"&gt;$$
B[i,w]=\left\{
                \begin{array}{ll}
                  B[i-1,w] \text{ if } w_i &amp;gt; w \\
                  \text{max}\{B[i-1, w], B[i-1, w-w_i] + b_i\} \text{ otherwise }
                \end{array}
              \right.
$$&lt;/div&gt;
&lt;p&gt;The idea for above recursion formula is that the best subset of &lt;span class="math"&gt;\(S_i\)&lt;/span&gt; that
has total weight &lt;span class="math"&gt;\(w\)&lt;/span&gt; either contains item &lt;span class="math"&gt;\(i\)&lt;/span&gt; or not. First case: &lt;span class="math"&gt;\(w_i &amp;gt; w\)&lt;/span&gt;. 
Item &lt;span class="math"&gt;\(i\)&lt;/span&gt; can’t be part of the solution because including item &lt;span class="math"&gt;\(i\)&lt;/span&gt; will have
the total weight greater than &lt;span class="math"&gt;\(w\)&lt;/span&gt;, which is unacceptable. The second case:
&lt;span class="math"&gt;\(w_i \le w\)&lt;/span&gt;. Item &lt;span class="math"&gt;\(i\)&lt;/span&gt; &lt;strong&gt;can&lt;/strong&gt; be in the solution, and we choose the case 
with greater value: not contain &lt;span class="math"&gt;\(i\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(B[i-1, w]\)&lt;/span&gt;) or contain 
&lt;span class="math"&gt;\(i\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(B[i-1, w-w_i] + b_i\)&lt;/span&gt;).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;As you can see from recursive formula, the solution &lt;span class="math"&gt;\(B[i,w]\)&lt;/span&gt; reuses
the solution to &lt;span class="math"&gt;\(B[i-1, w]\)&lt;/span&gt; and &lt;span class="math"&gt;\(B[i-1, w-w_i]\)&lt;/span&gt;, which is the signature of
dynamic programming.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The algorithm is below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;for w = 0 to W 
    B[0,w] = 0
for i = 1 to n 
    B[i,0] = 0 
for i = 1 to n
    for w = 1 to W
        if w_i &amp;lt;=w  //item i can be part of the solution 
            if b_i + B[i-1,w-w_i ] &amp;gt; B[i-1,w]
                B[i,w] = b_i + B[i-1, w-w_i]
            else
                B[i,w] = B[i-1,w]
        else 
            B[i,w] = B[i-1,w] // w_i &amp;gt; w
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The running time for this algorithm is &lt;span class="math"&gt;\(O(n*W)\)&lt;/span&gt; because of the double for loop. To understand this algorithm,
let’s take a look at an example:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Weight &lt;span class="math"&gt;\(w_i\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benefit &lt;span class="math"&gt;\(b_i\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Suppose &lt;span class="math"&gt;\(W = 5\)&lt;/span&gt; and with algorithm above, we essentially fill out a table like following:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;i \ w&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Each cell in the above table represents &lt;span class="math"&gt;\(B[i,w]\)&lt;/span&gt; and the table looks like above after we executing 
the first two for loops&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;W&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;[&lt;span class="mi"&gt;0&lt;/span&gt;,&lt;span class="nv"&gt;w&lt;/span&gt;]&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;B&lt;/span&gt;[&lt;span class="nv"&gt;i&lt;/span&gt;,&lt;span class="mi"&gt;0&lt;/span&gt;]&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, let’s take a look at &lt;span class="math"&gt;\(B[1,1]\)&lt;/span&gt;. We have &lt;span class="math"&gt;\(i = 1, b_i = 3, w_i = 2, w = 1\)&lt;/span&gt;, and since &lt;span class="math"&gt;\(w_i &amp;gt; w\)&lt;/span&gt;, and by our
algorithm, we have &lt;span class="math"&gt;\(B[i,w] = B[i-1,w]\)&lt;/span&gt;, which is &lt;span class="math"&gt;\(B[0,1]\)&lt;/span&gt;. Thus, &lt;span class="math"&gt;\(B[1,1] = 0\)&lt;/span&gt; and the table becomes&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;i \ w&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We can fill out the table like this and have&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;i \ w&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Now, we have the maximum benefit value given the capacity of the knapsack, which is &lt;span class="math"&gt;\(B[4,5] = 7\)&lt;/span&gt;. 
The next question is to find out what items we should put inside the knapsack in order to have
this maximum benefit (i.e., &lt;span class="math"&gt;\(7\)&lt;/span&gt;). The algorithm is below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Let i = n and k = W
while i &amp;gt; 0 and k &amp;gt; 0
    if B[i,k] != B[i-1,k], then
        mark the ith item as in the knapsack
        i = i - 1
        k = k - w_i
    else
        i = i - 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s first take a look a few examples on how this algorithm runs and then we will
see the intuition behind this algorithm. In our example, we start with
&lt;span class="math"&gt;\(i = 4, k = 5, w_i = 5, B[i,k] = 7, B[i-1,k] = 7\)&lt;/span&gt;. Then, by our algorithm, we
decrements &lt;span class="math"&gt;\(i\)&lt;/span&gt; and move on. Same situtation happens when &lt;span class="math"&gt;\(i=3\)&lt;/span&gt; because &lt;span class="math"&gt;\(B[i,k] = B[i-1,k]\)&lt;/span&gt;.
Now, when &lt;span class="math"&gt;\(i = 2\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(B[i,k] = 7\)&lt;/span&gt; and &lt;span class="math"&gt;\(B[i-1,k] = 3\)&lt;/span&gt;. Thus, we mark &lt;span class="math"&gt;\(i=2\)&lt;/span&gt;th item
as in the knapsack and this item has weight &lt;span class="math"&gt;\(w_2 = 3\)&lt;/span&gt; and &lt;span class="math"&gt;\(b_2 = 4\)&lt;/span&gt;. Now, we decrement &lt;span class="math"&gt;\(i\)&lt;/span&gt; 
and update &lt;span class="math"&gt;\(k\)&lt;/span&gt; by &lt;span class="math"&gt;\(k = k - w_i = 5 - 4 = 3\)&lt;/span&gt;. Now, we are at &lt;span class="math"&gt;\(B[1,2]\)&lt;/span&gt; cell. We do the same
for &lt;span class="math"&gt;\(i = 1\)&lt;/span&gt; and it turns out &lt;span class="math"&gt;\(i = 1\)&lt;/span&gt; should also be inside the knapsack.&lt;/p&gt;
&lt;p&gt;You may now probably tell that the idea for the algorithm to find the exactly items inside
the knapsack is that &lt;em&gt;we always want to put the item inside the knapsack that has value 
gain&lt;/em&gt;. This is just like “marginal thinking” in Economics. For example, we don’t 
want to put &lt;span class="math"&gt;\(i = 4\)&lt;/span&gt;th item inside knapsack because from &lt;span class="math"&gt;\(i = 3\)&lt;/span&gt; to &lt;span class="math"&gt;\(i = 4\)&lt;/span&gt;, there is no value
gain (i.e. &lt;span class="math"&gt;\(B[i,k] = B[i-1,k] = 5\)&lt;/span&gt;).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The detailed implementation of the algorithm in C can be found from 
&lt;a href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/knapsack/knapsack.c"&gt;my code-for-blog repo&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="0-x-knapsack-problem"&gt;0-x knapsack problem&lt;/h2&gt;
&lt;p&gt;0-x knapsack problem is a generalization of 0-1 knapsack problem in the sense that
for item &lt;span class="math"&gt;\(i\)&lt;/span&gt; we can load multiple of it into our knapsack. Let’s use &lt;span class="math"&gt;\(x_i\)&lt;/span&gt; to denote
the number of &lt;span class="math"&gt;\(i\)&lt;/span&gt;th item that is loaded into the knapsack. One requirement to &lt;span class="math"&gt;\(x_i\)&lt;/span&gt;
is that it has to be integer-valued.&lt;/p&gt;
&lt;p&gt;The problem formulation and subproblem definition is just like the 0-1 knapsack problem.
The only thing we need to do is to adjust is the recursive solution to subproblems:&lt;/p&gt;
&lt;div class="math"&gt;$$
B[i,w]=\left\{
                \begin{array}{ll}
                  B[i-1,w] \text{ if } w_i &amp;gt; w \\
                  \max_{0 \le x_i \le \lfloor\frac{w}{w_i}\rfloor}\{B[i-1, w], B[i-1, w-w_ix_i] + b_ix_i\} \text{ otherwise }
                \end{array}
              \right.
$$&lt;/div&gt;
&lt;p&gt;When &lt;span class="math"&gt;\(w_i &amp;gt; w\)&lt;/span&gt;, we cannot include item &lt;span class="math"&gt;\(i\)&lt;/span&gt; at all. However, when &lt;span class="math"&gt;\(w_i &amp;lt; w\)&lt;/span&gt;, we have more options 
because we can include multiple of item &lt;span class="math"&gt;\(i\)&lt;/span&gt;. But, we cannot assign a value greater than &lt;span class="math"&gt;\(w/w_i\)&lt;/span&gt;
to &lt;span class="math"&gt;\(x_i\)&lt;/span&gt;. In addition, &lt;span class="math"&gt;\(w/w_i\)&lt;/span&gt; may not be an integer. So, we &lt;span class="math"&gt;\(x_i\)&lt;/span&gt; should be in the range 
&lt;span class="math"&gt;\(0 \le x_i \le \lfloor w/w_i \rfloor\)&lt;/span&gt;, where the notation &lt;span class="math"&gt;\(\lfloor x \rfloor\)&lt;/span&gt; is, for any given &lt;span class="math"&gt;\(x\)&lt;/span&gt;, 
defined as the greatest integer less than or equal to &lt;span class="math"&gt;\(x\)&lt;/span&gt;. The algorithm is shown below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;0,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w_i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cands_B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;hold&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;possible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;cands_B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i-1, w - w_i * x_i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b_i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cands_B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;associated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i-1,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x_i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;associated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i-1,w&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s walk through an example to better understand the algorithm idea:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Weight &lt;span class="math"&gt;\(w_i\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Benefit &lt;span class="math"&gt;\(b_i\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;span class="math"&gt;\(W = 8\)&lt;/span&gt; in our example. The algorithm essentially
tries to build fill out two tables &lt;span class="math"&gt;\(B[i,w]\)&lt;/span&gt; table like
the 0-1 knapsack problem:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;i \ w&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;th&gt;6&lt;/th&gt;
&lt;th&gt;7&lt;/th&gt;
&lt;th&gt;8&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;and &lt;span class="math"&gt;\(x[i,w]\)&lt;/span&gt; table to keep track of the optimal
value of &lt;span class="math"&gt;\(x_i\)&lt;/span&gt; for each &lt;span class="math"&gt;\(i\)&lt;/span&gt; and &lt;span class="math"&gt;\(w\)&lt;/span&gt;&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;i \ w&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;th&gt;6&lt;/th&gt;
&lt;th&gt;7&lt;/th&gt;
&lt;th&gt;8&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For &lt;span class="math"&gt;\(i = 1\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(w_i = 3, b_i = 4\)&lt;/span&gt;. Thus, when
&lt;span class="math"&gt;\(w = 0,1,2\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(B[i,w] = 0\)&lt;/span&gt; and &lt;span class="math"&gt;\(x[i,w] = 0\)&lt;/span&gt; as well.
When &lt;span class="math"&gt;\(w = 3\)&lt;/span&gt;, we can include &lt;span class="math"&gt;\(w_i\)&lt;/span&gt; inside the knapsack and
we calculate the following:&lt;/p&gt;
&lt;div class="math"&gt;$$
B[1,3] = \max \{B[0,3], B[0,3-3*1]+4*1\} = \max \{0, 0+4\} = 4
$$&lt;/div&gt;
&lt;p&gt;So, we fill in &lt;span class="math"&gt;\(B[1,3] = 4\)&lt;/span&gt; and &lt;span class="math"&gt;\(x[1,3] = 1\)&lt;/span&gt;. We can repeatedly
doing this for other &lt;span class="math"&gt;\(i\)&lt;/span&gt;s. We can take a look at the values
from another perspective like the tables below:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;B[1,w]&lt;/th&gt;
&lt;th&gt;w&lt;/th&gt;
&lt;th&gt;x_1*&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;B[2,w]&lt;/th&gt;
&lt;th&gt;w&lt;/th&gt;
&lt;th&gt;x_2*&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;B[3,w]&lt;/th&gt;
&lt;th&gt;w&lt;/th&gt;
&lt;th&gt;x_3*&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The values are all the same but the data are organized differently. Clearly, two tables
are better than three tables in terms of space. As you can see from either two sets of 
tables, the maximum benefit we can achieve is &lt;span class="math"&gt;\(9\)&lt;/span&gt;, which is entry of &lt;span class="math"&gt;\(B[3,8]\)&lt;/span&gt;. In order to find out the exact
composition of the knapsack, we can work backwards from &lt;span class="math"&gt;\(i = 3\)&lt;/span&gt;. With &lt;span class="math"&gt;\(i = 3\)&lt;/span&gt; and &lt;span class="math"&gt;\(w = 8\)&lt;/span&gt;, &lt;span class="math"&gt;\(x_1 = 1\)&lt;/span&gt;. Since
&lt;span class="math"&gt;\(w_1 = 5\)&lt;/span&gt; and &lt;span class="math"&gt;\(W = 8\)&lt;/span&gt;, then we have &lt;span class="math"&gt;\(3\)&lt;/span&gt; left in knapsack in terms of weight. For &lt;span class="math"&gt;\(i = 2\)&lt;/span&gt; and &lt;span class="math"&gt;\(w = 3\)&lt;/span&gt; (because
we have only &lt;span class="math"&gt;\(3\)&lt;/span&gt; left in our knapsack weight capacity), &lt;span class="math"&gt;\(x_2 = 0\)&lt;/span&gt;. Then, for &lt;span class="math"&gt;\(i = 1, w = 3\)&lt;/span&gt; (we still have &lt;span class="math"&gt;\(3\)&lt;/span&gt;
budge left), &lt;span class="math"&gt;\(x_1 = 1\)&lt;/span&gt;. Thus, our optimal choice for each item is &lt;span class="math"&gt;\(x_1 = 1, x_2 = 0, x_3 = 1\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="fractional-knapsack-problem"&gt;Fractional knapsack problem&lt;/h2&gt;
&lt;p&gt;Another type of knapsack problem is the fractional knapsack problem. In this setting, &lt;em&gt;the item is divisible&lt;/em&gt;. In
other words, we can take fraction of item. This problem 
can also be considered as a generalization of 0-x knapsack problem by not requiring &lt;span class="math"&gt;\(x_i\)&lt;/span&gt; has to be integer value.
In this case, we actually use the &lt;em&gt;greedy algorithm&lt;/em&gt; paradigm instead of &lt;em&gt;dynamic programming&lt;/em&gt; paradigm to solve the
problem. &lt;/p&gt;
&lt;p&gt;Let’s use the same example as 0-x knapsack problem. In this case, we actually calculate the benefit per unit of weight
first:&lt;/p&gt;
&lt;div class="math"&gt;$$
\frac{b_1}{w_1} = \frac{4}{3}, \frac{b_2}{w_2} = \frac{6}{8}, \frac{b_3}{w_3} = \frac{5}{5}
$$&lt;/div&gt;
&lt;p&gt;as you can see, the first item gives the maximum benefit per unit of weight and we want to load this item as much as possible,
which is &lt;span class="math"&gt;\(W/w_1 = 8/3\)&lt;/span&gt;. The reason we can use greedy algorithm to do this is because we can have fraction of item. If we don’t
allow the fraction of item like we do in the 0-x knapsack problem, this appraoch will get suboptimal solution: we can only
have &lt;span class="math"&gt;\(2\)&lt;/span&gt; item &lt;span class="math"&gt;\(1\)&lt;/span&gt; (because &lt;span class="math"&gt;\(\lfloor\frac{8}{3}\rfloor = 2\)&lt;/span&gt;) and the last &lt;span class="math"&gt;\(2\)&lt;/span&gt; knapsack weight capacity is not big enough to 
fit any item any more. Thus, the benefit we get in this case is &lt;span class="math"&gt;\(2*4 = 8\)&lt;/span&gt;, which is smaller than &lt;span class="math"&gt;\(9\)&lt;/span&gt; our maximum benefit obtained
from &lt;em&gt;dynamic programming&lt;/em&gt; approach.&lt;/p&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.utdallas.edu/~scniu/OPRE-6201/documents/DP3-Knapsack.pdf"&gt;UT-Dallas Introduction to Operations Research course material&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cse.unl.edu/~goddard/Courses/CSCE310J/Lectures/Lecture8-DynamicProgramming.pdf"&gt;University of Nebraska CSCE 310J Data Structures and Algorithms lecture note&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;See &lt;a href="https://stackoverflow.com/questions/13538459/difference-between-divide-and-conquer-algo-and-dynamic-programming"&gt;Difference between Divide and Conquer Algo and Dynamic Programming SO post&lt;/a&gt; &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="dynamic programming"></category><category term="greedy algorithm"></category></entry><entry><title>Understanding how function call works</title><link href="https://zhu45.org/posts/2017/Jul/30/understanding-how-function-call-works/" rel="alternate"></link><published>2017-07-30T00:21:00+08:00</published><updated>2017-07-30T00:21:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-07-30:/posts/2017/Jul/30/understanding-how-function-call-works/</id><summary type="html">&lt;p&gt;Understand call stack in programming language (i.e. C)&lt;/p&gt;</summary><content type="html">&lt;p&gt;Understanding assembly language is crucial for system programming. Some nasty defects of the system
can only be solved by digging into the assembly level of the program. In this post, I’ll revisit 
call stack concept as a way to understand how function call works under the cover of high-level language.
In addition, this post belongs to part of future work mentioned in &lt;a href="https://zhu45.org/posts/2017/Jan/22/num-of-function-calls-in-recursive-fibonacci-routine/"&gt;my post back in January&lt;/a&gt;.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#addressing-mode"&gt;Addressing mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#main-course"&gt;Main course&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#some-terms"&gt;Some terms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#stack"&gt;Stack&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#calling-a-function"&gt;Calling a function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#writing-a-function"&gt;Writing a function&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#setup"&gt;Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#using-the-stack-frame"&gt;Using the stack frame&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#cleanup"&gt;Cleanup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#two-examples"&gt;Two examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#future-works"&gt;Future works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#links-to-resources"&gt;Links to resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="addressing-mode"&gt;Addressing mode&lt;/h2&gt;
&lt;p&gt;Before we jump into the actual material. I want to briefly revisit the various ways for assembly language
accessing the data in memory (i.e., addressing mode). 
The following table is adapted from CSAPP (2nd edition):&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Operand Value&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Immediate&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\($Imm\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(Imm\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Immediate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Register&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(E_a\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(R[E_a]\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Register addressing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(Imm\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(M[Imm]\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Direct addressing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\((E_a)\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(M[R[E_b]]\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Indirect addressing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(Imm(E_b, E_i, s)\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span class="math"&gt;\(M[Imm+R[E_b]+(R[E_i]\cdot s)]\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Scaled indexed addressing &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In the above table, &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(Imm\)&lt;/span&gt; refers to a constant value, e.g. &lt;span class="math"&gt;\(\mathtt{0x8048d8e}\)&lt;/span&gt; or &lt;span class="math"&gt;\(\mathtt{48}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(E_x\)&lt;/span&gt; refers to a register, e.g. &lt;span class="math"&gt;\(\mathtt{\%eax}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(R[E_x]\)&lt;/span&gt; refers to the value stored in register &lt;span class="math"&gt;\(E_x\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(M[x]\)&lt;/span&gt; refers to the value stored at memory address &lt;span class="math"&gt;\(x\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="main-course"&gt;Main course&lt;/h2&gt;
&lt;p&gt;Now, let’s bring our main course onto the table: understanding how function works. I’ll
first clear up some terms we will use during the explanation. Then, we’ll take a look
at the stack and understand how it supports function calls. Lastly, we’ll examine
two assembly programs and understand the whole picture of function calls.&lt;/p&gt;
&lt;h3 id="some-terms"&gt;Some terms&lt;/h3&gt;
&lt;p&gt;Let’s first consider what the key elements we need in order to form a function:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;function name&lt;/p&gt;
&lt;p&gt;A function’s name is a symbol that represents the address where the function’s code starts. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;function arguments&lt;/p&gt;
&lt;p&gt;A function’s arguments (aka. parameters) are the data items that are explicitly given to
the function for processing. For example, in mathematics, there is a &lt;span class="math"&gt;\(\sin\)&lt;/span&gt; function. If
you were to ask a computer to find the &lt;span class="math"&gt;\(\sin (2)\)&lt;/span&gt;, &lt;span class="math"&gt;\(\sin\)&lt;/span&gt; would be the function’s name, 
and &lt;span class="math"&gt;\(2\)&lt;/span&gt; would be the argument (or parameter).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;local variables&lt;/p&gt;
&lt;p&gt;Local variables are data storage that a function uses while processing that
is thrown away when it returns. It’s knid of like a scratch pad of paper.
Functions get a new piece of paper every time they are activated, and they have to throw
it away when they are finished processing. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;return address&lt;/p&gt;
&lt;p&gt;The return address is an “invisible” parameter in that it isn’t directly used
during the function. The return address is a parameter which tells the function
where to resume executing after the function is completed. This is needed because
functions can be called to do processing from many different parts of our program,
and the function needs to be able to get back to wherever it was called from. 
In most programming languages, this parameter is passed automatically when the function
is called. In assembly language, the &lt;code&gt;call&lt;/code&gt; instruction handles passing the return 
address for you, and &lt;code&gt;ret&lt;/code&gt; handles using that address to return back to where
you called the function from.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;return value&lt;/p&gt;
&lt;p&gt;The return value is the main method of transferring data back to the main program. 
Most programming languages only allow a sinlge return value for function.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The way that the variables are stored and the parameters and return values
are transferred by the computer varies from language to language. This variance
is known as a language’s &lt;em&gt;calling convention&lt;/em&gt;, because it describes how functions
expect to get and receive data when they are called. In this post, I’ll 
follow C programming language calling convention.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="stack"&gt;Stack&lt;/h3&gt;
&lt;p&gt;Each computer program that runs uses a region of memory called the &lt;strong&gt;stack&lt;/strong&gt; to enable functions to work
properly. Machine uses the stack to pass function arguments, to store return information, to save
registers for later restoration, and for local variables.
The portion of the stack allocated for a single function call is called a &lt;strong&gt;stack frame&lt;/strong&gt;. In other words,
for each function call, new space (i.e., stack frame) is created on the stack. &lt;/p&gt;
&lt;p&gt;The computer’s stack lives at the very top addresses of memory. As the name suggests, stack is a stack
data structure with the “top” of the stack growing from the &lt;a href="https://zhu45.org/images/heap.png"&gt;high value addresses towards low values addresses&lt;/a&gt;.
We use &lt;span class="math"&gt;\(\mathtt{push \text{ } S}\)&lt;/span&gt; to push the source onto stack, and we use
&lt;span class="math"&gt;\(\mathtt{pop \text{ } D}\)&lt;/span&gt; to remove the top value from the stack and place it into a destination
(i.e. a register or memory location). We use the stack register, &lt;span class="math"&gt;\(\mathtt{\%esp}\)&lt;/span&gt; as a pointer
to the top of the stack, which at the same time, is the top of topmost stack frame.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Pointer here means that the stack register contains an address in memory instead of a regular value.
Specifically, the stack register now contains the address, which has the top value of the stack 
in it. With this description, we can see that to access the value on the top of the stack without
removing it, we can do &lt;code&gt;(%esp)&lt;/code&gt;, which is indirect addressing mode.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;When we talk about function calls, what we really care about is the topmost stack frame because 
that’s the memory region that is associated with our current function calls. CSAPP (2nd edition)
has a nice picture about what the whole stack looks like:&lt;/p&gt;
&lt;p&gt;&lt;img alt="stack frame structure" class="img-responsive" src="https://zhu45.org/images/stack-frame-structure.png"/&gt;&lt;/p&gt;
&lt;p&gt;If some texts (i.e. “Saved %ebp”) or layout (i.e. the order of arguments) don’t make sense to you,
don’t worry. I’ll talk about them immediately.&lt;/p&gt;
&lt;h4 id="calling-a-function"&gt;Calling a function&lt;/h4&gt;
&lt;p&gt;Before executing a function, a program pushes all of the parameters for the function
onto the stack in the reverse order that they are documented. Then the program
issues a &lt;code&gt;call&lt;/code&gt; instruction indicating which function it wishes to start. 
The &lt;code&gt;call&lt;/code&gt; instruction does two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First it pushes the address of the next instruction, which is the return address, onto
the stack.&lt;/li&gt;
&lt;li&gt;Then, it modifies the instruction pointer &lt;span class="math"&gt;\(\mathtt{\%eip}\)&lt;/span&gt; to point to the start of the function.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;When you call a function, you should assume that everything currently
in your registers will be wiped out. The only register that is guaranteed
to be left with the value it started with is &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt; (why? see
“Writing a function” section below). Thus, if there are registers
you want to save before calling a function, you need to save them
by pushing them on the stack before pushing the function’s parameters.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;So, at the time the function starts, the stack looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="nx"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;esp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As noted previously, the stack pointer holds the address, which contains return address as its value.&lt;/p&gt;
&lt;h4 id="writing-a-function"&gt;Writing a function&lt;/h4&gt;
&lt;p&gt;Writing a function in x86 assembly essentially contains of three parts: setup, using the stack frame to perform
task, cleanup. The setup and cleanup steps are the same acrossed all the function calls. All three steps
will be explained in details.&lt;/p&gt;
&lt;h5 id="setup"&gt;Setup&lt;/h5&gt;
&lt;p&gt;During the setup, the following two instructions are carried out immediately:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;
&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first instruction is to save the current base pointer register (aka frame pointer), &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt;. 
The base pointer is a special register used for accessing function parameters and local 
variables.The stack frame is delimited by two pointers: &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt; serves as the pointer pointing
to the bottom of the stack frame and &lt;span class="math"&gt;\(\mathtt{\%esp}\)&lt;/span&gt; serves as the pointer pointing to the 
top of the stack frame. As pointed out earlier, each function call has its own stack frame.
Once the current function (i.e. callee) is done, we need to resume the execution of the caller function. 
This means that we need to restore the caller’s base pointer register &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt; when
we are done with callee function. Thus, we need to save the current base pointer register, 
which is the caller’s for the future caller stack frame restoration.&lt;/p&gt;
&lt;p&gt;Once we are done with saving the caller’s &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt;, we can now setup current stack frame’s
&lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt; by doing &lt;code&gt;movl %esp %ebp&lt;/code&gt;. The reason for this is that we can now be 
able to access the function parameters that are pushed earlier onto the stack by caller function
as fixed indexes from the base pointer. We cannot use stack pointer directly for accessing
parameters because the stack pointer can move while the function is executing. &lt;/p&gt;
&lt;p&gt;At this point, the stack looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nx"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Old&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;ebp&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;esp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h5 id="using-the-stack-frame"&gt;Using the stack frame&lt;/h5&gt;
&lt;p&gt;Once we have performed the fix setup, we can now use the stack frame to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;save registers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We need to push all the callee-save registers by convention onto the stack. By convention,
registers &lt;span class="math"&gt;\(\mathtt{\%eax}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathtt{\%edx}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathtt{\%ecx}\)&lt;/span&gt; are classified as caller-save 
registers, and &lt;span class="math"&gt;\(\mathtt{\%ebx}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\mathtt{\%esi}\)&lt;/span&gt;, and &lt;span class="math"&gt;\(\mathtt{\%edi}\)&lt;/span&gt; are classified as callee-save
registers. The caller-save registers mean that the caller function is responsible saving these
register values because the callee is free to override these register values. On the other hand,
the callee-save registers mean that the callee function must save those registers values by pushing
them onto the stack before overwritting them, and restore them before the returning because the
caller may need these values for its future computations. &lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Save registers step is not mandatory. If your caller function (or higher-level functions)
don’t use all these callee-save registers, you are free to skip this step.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;local variables&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The function reserves space on the stack for any local variables it needs. Space for data with
no specified initial value can be allocated on the stack by simply decrementing the stack pointer
by an appropriate amount. Similarly, space can be deallocated by incrementing pointer. Suppose
we are going to need two words of memory to run a function. We can simply move the stack pointer
down two words to serve the space:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;subl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Allocate 8 bytes of space on the stack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While it is possible to make space on the stack as needed in a function body, it is generally
more efficient to allocate this space all at once at the beginning of the function. This way,
we are free of worring about clobbering them with pushes that we may make for next function calls
(i.e. push arguments and return address for the function calls contained inside the current
function, which all happens in “Argument build area” in the above picture).&lt;/p&gt;
&lt;p&gt;Suppose we save &lt;span class="math"&gt;\(\mathtt{\%ebx}\)&lt;/span&gt; (i.e. callee-save register),
and with our two words for local storage, our stack now looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="n"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Argument&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Old&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%esp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;%ebx&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variable1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variable2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;---&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;%esp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, we can now access all of the data we need for this function by
using base pointer addressing using different offsets from &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt;.
&lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt; was made specifically for this purpose, which is why it is
called the base pointer. &lt;/p&gt;
&lt;h5 id="cleanup"&gt;Cleanup&lt;/h5&gt;
&lt;p&gt;When a function is done executing, it does the following three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It stores its return value in &lt;span class="math"&gt;\(\mathtt{\%eax}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;It frees the stack space it allocated by adding the same amount to the stack pointer （i.e., &lt;code&gt;addl $8 %esp&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;It pops off the registers it saved earlier (i.e., &lt;code&gt;popl %ebx&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;It resets the stack to what it was when it was called (it gets rid of the current stack frame
and puts the stack frame of the caller back into effect)&lt;/li&gt;
&lt;li&gt;It returns control back to wherever it was called from. This is done using the &lt;code&gt;ret&lt;/code&gt; instruction,
which pops whatever value is at the top of the stack, and sets the instruction pointer %\mathtt{\%eip}$
to that value.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The reason we have to restore the caller’s base pointer register before calling &lt;code&gt;ret&lt;/code&gt; is due to the
structure of our current stack frame: in our current stack frame, the return address is not
at the top of the stack. Therefore, in order to make the return address to be the top of the stack frame,
we need to move the stack pointer &lt;span class="math"&gt;\(\mathtt{\%esp}\)&lt;/span&gt; to the current stack frame base pointer &lt;span class="math"&gt;\(\mathtt{\%ebp}\)&lt;/span&gt;
and restore the caller’s frame pointer first. Then, the return address will be the top of the stack.
Since we need to perform caller’s frame pointer restoration anyway, everything just works out.&lt;/p&gt;
&lt;p&gt;Thus, to return from the function you have to do the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Set stack pointer back to the beginning of the frame&lt;/span&gt;
&lt;span class="nf"&gt;popl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;# Restore the caller's base pointer and now stack pointer pointing to Return address&lt;/span&gt;
&lt;span class="nf"&gt;ret&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# Since stack pointer pointing to return address, we can now call ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The step 2 and 3 are unecessary if we don’t save any registers at all. The reason we do step 2
is that we need to move the stack pointer pointing to the saved registers. If there are
no saved registers, the step 4 can achieve the same effect as step 3 because
after you move the stack pointer back, future stack pushes will likely overwrite everything you
put there. &lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="two-examples"&gt;Two examples&lt;/h3&gt;
&lt;p&gt;Now, we can take a look at two examples: the first one is to calculate the power given two numbers: one
as the base and the other one as the power. The second example calculate the factorial of
a given number, which demonstrates how the recursive function is done.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# PURPOSE: Program to illustrate how functions work&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#          This program will compute the value of  2^3 + 5^2&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# Everything in the main program is stored in registers,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# so the data section doesn't have anything.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;.data&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;.text&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.globl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;_start&lt;/span&gt;

&lt;span class="nl"&gt;_start:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$3&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="c1"&gt;# push second argument&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$2&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="c1"&gt;# push first argument&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;power&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;# call the function&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;addl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# move the stack pointer back&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;# save the first answer before calling the next function&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$2&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="c1"&gt;# push second argument&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$5&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="c1"&gt;# push first argument&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;power&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;# call the function&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;addl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# move the stack pointer back&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;popl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="c1"&gt;# The second answer is already in %eax. We saved the&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="c1"&gt;# first answer onto the stack, so now we can just pop&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="c1"&gt;# it out into %ebx&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;addl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="c1"&gt;# add them together, the result is in %ebx&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# exit (%ebx is returned)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$0x80&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# PURPOSE: This function is used to compute the value of a number raised to a power&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# INPUT: First argument - the base number&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#        Second argumnet - the power to raise it to&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# OUTPUT: Will give the result as a return value&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# NOTES: The power must be 1 or greater&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# VARIABLES:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#        %ebx - holds the base number&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#        %ecx - holds the power&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#        -4(%ebp) - holds the current result&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#        %eax is used for temporary storage&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;power&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;@function&lt;/span&gt;
&lt;span class="nl"&gt;power:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;# save old base pointer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="c1"&gt;# make stack pointer the base pointer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;subl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# get room for our local storage&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# put first argument in %eax&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ecx&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;# put second argument in %ecx&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;# store current result&lt;/span&gt;

&lt;span class="nl"&gt;power_loop_start:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;cmpl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ecx&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# if the power is 1, we are done&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;je&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;end_power&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;# move the current result into %eax&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;imull&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# multiply the current result by the base number&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;# store the current result&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;decl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ecx&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="c1"&gt;# decrease the power&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;jmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;power_loop_start&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;# run for the next power&lt;/span&gt;

&lt;span class="nl"&gt;end_power:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;# return value goes in %eax&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="c1"&gt;# restore the stack pointer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="c1"&gt;# restore the base pointer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The key to understand the function call is to trace through the status of stack frame. One thing to 
highlight as a side note is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;.type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;power&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="na"&gt;@function&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tells the linker that the symbol power should be treated as a function. 
Since this program is only in one file, it would work just the same with this left out. However, it is good practice.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;To run the program on 64-bit platform, we need to simulate 32-bit environment by assembling and linking our program
like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;as --32 power.s -o power.o; 
ld -m elf_i386 -s power.o -o power&lt;/code&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# PURPOSE: - Given a number, this program computes the factorial. For example,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#            the factorial of 3 is 3 * 2 * 1, or 6. The factorial of&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#            4 is 4 * 3 * 2 * 1, or 24, and so on.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# This program shows how to call a function recursively.&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;.data&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# This program has no global data&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;.text&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;_start&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;factorial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# this is unneeded unless we want to share&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="c1"&gt;# this function among other programs&lt;/span&gt;

&lt;span class="nl"&gt;_start:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$4&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# The factorial takes one argument - the number we want&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="c1"&gt;# a factorial of. So, it gets pushed.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;factorial&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# run the factorial function&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;addl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;# scrubs the parameter that was pushed on the stack&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# factorial returns the answer in %eax, but we want it&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="c1"&gt;# in %ebx to send it as our exit status&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;# call the kernel's exit function&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$0x80&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# This is the actual function definition&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;.type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;@function&lt;/span&gt;
&lt;span class="nl"&gt;factorial:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;# standard function stuff - we have to restore %ebp&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# to its prior state before returning, so we have to push it&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# This is because we don't want to modify the stack pointer&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# so we use %ebp&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# This moves the first argument to %eax&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# 4(%ebp) holds the return address, and 8(%ebp) holds the first parameter&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;cmpl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;# if the number is 1, this is our base case, and we simply&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# return (1 is already in %eax as the return value)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;je&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;end_factorial&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;decl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# otherwise, decrease the value&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;pushl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;# push it for our call to factorial&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;factorial&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;# call factorial&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# %eax has the return value, so we reload our parameter&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# into %ebx&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;imull&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%eax&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# multiply that by the result of the last call to factorial&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# (in %eax) the answer is stored in %eax, which is good since&lt;/span&gt;
&lt;span class="w"&gt;                           &lt;/span&gt;&lt;span class="c1"&gt;# that's where return values go.&lt;/span&gt;
&lt;span class="nl"&gt;end_factorial:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;movl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%esp&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# standard function return stuff - we have to restore&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;popl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%ebp&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# %ebp and %esp to where they were before the function started&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;ret&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;# return to the function (this pops the return value, too)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One good practice we should note is that we should always clean up our stack parameter after a function 
call returns. In this program, we do &lt;code&gt;addl $4, %esp&lt;/code&gt; immediately after we &lt;code&gt;call factorial&lt;/code&gt; in our &lt;code&gt;_start&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="future-works"&gt;Future works&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;For this post, I assume we work with x86 32-bit processor. It’s interesting to further
investigate how the things changed for the 64-bit world.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://dbp-consulting.com/tutorials/debugging/basicAsmDebuggingGDB.html"&gt;Basic Assembler Debugging with GDB by Patrick Horgan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.csee.umbc.edu/~cpatel2/links/310/nasm/gdb_help.shtml"&gt;Using gdb for Assembly Language Debugging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf"&gt;x64 Cheat Sheet - Brown CS 33&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://savannah.spinellicreations.com/pgubook/ProgrammingGroundUp-1-0-booksize.pdf"&gt;Programming from the Ground Up&lt;/a&gt; Chapter 3,4&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Computer-Systems-Programmers-Perspective-2nd/dp/0136108040"&gt;Computer Systems: A Programmer’s Perspective (CSAPP) (2nd Edition)&lt;/a&gt; Section 3.7&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;For scaled indexed addressing, it actually includes both base pointer addressing mode 
(i.e. &lt;code&gt;movl 4(%eax), %ebx&lt;/code&gt;) and indexed addressing mode 
(i.e., &lt;code&gt;movl string_start(, %ecx, 1), %eax&lt;/code&gt;). &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="programming languages"></category><category term="assembly language"></category><category term="call stack"></category></entry><entry><title>Andrew Ng's ML Week 06, 11</title><link href="https://zhu45.org/posts/2017/Jul/21/andrew-ngs-ml-week-06-11/" rel="alternate"></link><published>2017-07-21T12:51:00+08:00</published><updated>2017-07-21T12:51:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-07-21:/posts/2017/Jul/21/andrew-ngs-ml-week-06-11/</id><summary type="html">&lt;p&gt;Advice on building a machine learning system from course&lt;/p&gt;</summary><content type="html">&lt;p&gt;I actually &lt;a href="https://www.coursera.org/account/accomplishments/verify/58VFP5LF4UXV"&gt;finished the course&lt;/a&gt; 
on June 25th. In this page, I’ll
summarize various advices and tips given by Prof. Andrew Ng on how to build
a effective machine learning system.&lt;/p&gt;
&lt;p&gt;To be honest, I used to think this part of material may be not worth a post 
but as I dig deeper into the course I find out that this part is invaluable 
because it answers some commonly-seen questions when implementing a machine learning
system, which can be a huge time-saver. So, I think I need a post to record
those advices systematically. &lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#preface"&gt;Preface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#diagnostics"&gt;Diagnostics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#overfitting-vs-underfitting"&gt;Overfitting vs. Underfitting&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#model-selection-algorithm"&gt;Model selection algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#diagnosing-bias-vs-variance-which-is-which"&gt;Diagnosing bias vs. variance: which is which?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#regularization-how-to-choose-lambda"&gt;Regularization: how to choose \(\lambda\)?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#learning-curves"&gt;Learning curves&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#experience-underfitting"&gt;Experience underfitting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#experience-overfitting"&gt;Experience overfitting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#what-to-try-next"&gt;What to try next?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#neural-network-and-overfitting"&gt;Neural Network and overfitting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#error-analysis"&gt;Error analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ceiling-analysis"&gt;Ceiling analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#other-issues"&gt;Other issues&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#error-metrics-for-skewed-classes-precision-recall"&gt;Error metrics for skewed classes: Precision &amp;amp; Recall&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#skew-classes"&gt;Skew classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#precision-recall"&gt;Precision &amp;amp; Recall&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#f_1-score"&gt;\(F_1\) score&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#data-for-machine-learning"&gt;Data for machine learning&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="preface"&gt;Preface&lt;/h2&gt;
&lt;p&gt;One important question we may ask after implementing our machine learning algorithm
is that: how good is our learning algorithm? In addition, for instance, after
we have implemented regularized linear regression to predict housing prices 
and when we test our hypothesis on a new set of houses, we find that it makes
unacceptably large errors in the predictions, what we should try next? This post
aims to answer those questions.&lt;/p&gt;
&lt;p&gt;In this post, I will first take a look at the diagnostic to evaluate learning algorithm.
Then, I will define overfitting (high bias) and underfitting (high variance)
concepts and the concrete techniques to identify which is which. Afterwards, I will
talk about several ways to handle the problem and highlight some key points. Lastly,
we will take a look at some special cases when data is skewed or large.&lt;/p&gt;
&lt;h2 id="diagnostics"&gt;Diagnostics&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Diagnostics&lt;/strong&gt; is a test that you can run to gain insight what is or isn’t working
with a learning algorithm, and gain guidance as to how best to improve its performance.
We use &lt;strong&gt;test set error&lt;/strong&gt; as our basic metrics to evaulate our learning algorithm (hypothesis).&lt;/p&gt;
&lt;p&gt;We first shuffle our whole data set to eliminate the potential impact of data record
ordering. Then, we randomly choose &lt;span class="math"&gt;\(70\%\)&lt;/span&gt; of data set as our training set and the rest
&lt;span class="math"&gt;\(30\%\)&lt;/span&gt; as our test set. Mathematically, we denote training set: 
&lt;span class="math"&gt;\((x^{(1)}, y^{(1)}), (x^{(2)}, y^{(2)}), \dots, (x^{(m)}, y^{(m)})\)&lt;/span&gt; and we denote
test set as &lt;span class="math"&gt;\((x_{\text{test}}^{(1)}, y_{\text{test}}^{(1)}), (x_{\text{test}}^{(1)}, y_{\text{test}}^{(1)}) \dots (x_{\text{test}}^{(m_\text{test})}, y_{\text{test}}^{(m_\text{test})})\)&lt;/span&gt; with
&lt;span class="math"&gt;\(m_\text{test} = \text{no. of test examples}\)&lt;/span&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For linear regression, our test set error is calculated by the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Learn parameters &lt;span class="math"&gt;\(\theta\)&lt;/span&gt; from training data (i.e. minimizing training error &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;compute the test set error as follows:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;div class="math"&gt;$$
J_\text{test}(\theta) = \frac{1}{2m_\text{test}}\sum_{i=1}^{m_{test}}(h_\theta(x_{\text{test}}^{(i)})-y_\text{test}^{(i)})^2
$$&lt;/div&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For logistic regression, we can use similar way like linear regression to calculate
test set error but there is a way due to the nature of classification task. In this
case, we also call test set error as &lt;strong&gt;misclassification error&lt;/strong&gt; or &lt;strong&gt;(0/1 misclassification error)&lt;/strong&gt;:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="math"&gt;$$
\text{err}(h_\theta(x),y)=\left\{
                \begin{array}{ll}
                  1 \text{ if } h_\theta(x) \ge 0.5, y = 0 \text{ or if } h_\theta(x) &amp;lt; 0.5, y = 1 \\
                  0 \text{ otherwise }
                \end{array}
              \right.
$$&lt;/div&gt;
&lt;p&gt;This definition gives us a binary &lt;span class="math"&gt;\(0\)&lt;/span&gt; or &lt;span class="math"&gt;\(1\)&lt;/span&gt; error result based on a misclassification.
Then, we calculate test set error as &lt;/p&gt;
&lt;div class="math"&gt;$$
\text{Test error} = \frac{1}{m_\text{error}}\sum_{i=1}^{m_\text{test}}
\text{err}(h_\theta(x_\text{test}^{(i)}),y_\text{test}^{(i)})
$$&lt;/div&gt;
&lt;p&gt;This gives us the proportion of the test data that was misclassified.&lt;/p&gt;
&lt;p&gt;In addition to the test set error, we will define &lt;strong&gt;cross validation set error&lt;/strong&gt;
as well. Instead of dividing the whole data set as training set and test set, 
we can divide it into three parts: training set, corss validation (cv) set, and
test set, with proportion of data set as &lt;span class="math"&gt;\(60\%\)&lt;/span&gt;, &lt;span class="math"&gt;\(20\%\)&lt;/span&gt;, and &lt;span class="math"&gt;\(20\%\)&lt;/span&gt;. Mathematically,
similar to the notation of test set, we have &lt;span class="math"&gt;\((x_{\text{cv}}^{(1)}, y_{\text{cv}}^{(1)}), (x_{\text{cv}}^{(1)}, y_{\text{cv}}^{(1)}) \dots (x_{\text{cv}}^{(m_\text{cv})}, y_{\text{cv}}^{(m_\text{cv})})\)&lt;/span&gt; with
&lt;span class="math"&gt;\(m_\text{cv} = \text{no. of cv examples}\)&lt;/span&gt;. The purpose
of dividing data set in this way will be clear in the next section. &lt;/p&gt;
&lt;p&gt;Now, we summarize our metrics (training error, cross validation error, and test set error)
as follows:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
J_\text{train}(\theta) &amp;amp;=&amp;amp; \frac{1}{2m}\sum_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)})^2 \\
J_\text{cv}(\theta)    &amp;amp;=&amp;amp; \frac{1}{2m_\text{cv}}\sum_{i=1}^{m_{cv}}(h_\theta(x_{\text{cv}}^{(i)})-y_\text{cv}^{(i)})^2 \\
J_\text{test}(\theta)  &amp;amp;=&amp;amp; \frac{1}{2m_\text{test}}\sum_{i=1}^{m_{test}}(h_\theta(x_{\text{test}}^{(i)})-y_\text{test}^{(i)})^2
\end{eqnarray*}
$$&lt;/div&gt;
&lt;h2 id="overfitting-vs-underfitting"&gt;Overfitting vs. Underfitting&lt;/h2&gt;
&lt;p&gt;In &lt;a href="https://zhu45.org/posts/2017/May/05/andrew-ngs-ml-week-01-03/"&gt;week 01-03 post&lt;/a&gt;, we mention
the term &lt;em&gt;overfitting&lt;/em&gt; when we talk about regularization. Now, we explain it
in details. &lt;strong&gt;Overfitting&lt;/strong&gt; happens when we have too many features, the learning
hypothesis may fit the training set very well (i.e.
&lt;span class="math"&gt;\(J(\theta)=\frac{1}{2m} \sum_{i=1}^m(\theta^T x^{(i)}-y(i))^2 \approx 0\)&lt;/span&gt;) but
fail to generalize to new examples (i.e. predict prices on a new set of house). 
Take a look at the following three graphs&lt;/p&gt;
&lt;p&gt;&lt;img alt="overfitting example: linear regression" class="img-responsive" src="https://zhu45.org/images/overfitting.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;The first graph (leftmost) shows the result of fitting our training set
with a hypothesis: &lt;span class="math"&gt;\(h_\theta(x) = \theta_0 + \theta_1 x\)&lt;/span&gt;. You can see that
the data doesn’t really lie on straight line, and so the fit is not very good.
In this case, we call the scenario &lt;strong&gt;underfitting&lt;/strong&gt;, which means the model doesn’t
capture the data structure well. Another term for this is &lt;strong&gt;high bias&lt;/strong&gt;. One way
to think of &lt;strong&gt;high bias&lt;/strong&gt; is that the algorithm has strong preconception on
what the data should be, in our case, linear. In summary, underfitting, or high bias,
is when the form of our hypothesis function &lt;span class="math"&gt;\(h\)&lt;/span&gt; maps poortly to the trend of the data. 
It is usually caused by a function that is too simple or uses too few features.&lt;/p&gt;
&lt;p&gt;At the other extreme, shown by the rightmost graph, is &lt;strong&gt;overfitting&lt;/strong&gt;, or &lt;strong&gt;high variance&lt;/strong&gt;.
&lt;strong&gt;High variance&lt;/strong&gt; means that the function can almost fit any function: hypothesis
&lt;span class="math"&gt;\(h\)&lt;/span&gt; is too general and we don’t have enough data to constrain it. The overfitting or 
high variance is usually caused by a complicated function that creates a lot of unnecessary
curves and angles unrelated to the data. &lt;/p&gt;
&lt;p&gt;There are a couple of ways to tackle the overfitting problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Reduce number of features&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manually select which feature to keep&lt;/li&gt;
&lt;li&gt;Model selection algorithm&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Regularization, which can keep all the features, but reduce magnitude/values of parameters &lt;span class="math"&gt;\(\theta_j\)&lt;/span&gt;.
This way works well when we have a lot of features, each of which contributes a bit to predicting &lt;span class="math"&gt;\(y\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="model-selection-algorithm"&gt;Model selection algorithm&lt;/h3&gt;
&lt;p&gt;Once parameters &lt;span class="math"&gt;\(\theta_0, \theta_1, \dots\)&lt;/span&gt; were fit to some set of data (training set),
the error of the parameters as measured on that data (i.e. &lt;span class="math"&gt;\(J_\text{train}\theta\)&lt;/span&gt;) 
is likely to be lower than the actual generalization error. In other words, 
&lt;span class="math"&gt;\(J_\text{train}\theta\)&lt;/span&gt; will be a bad metric on predicting how well our hypothesis
will be generalized to new examples. So, how do we measure how well our hypothesis
will perform on new examples? In addition, how to select which model to use? Ideally,
we should pick the model that has the best performance on new examples. As you can tell,
these two questions are equivalent and are all centered around the metrics we 
use for reporting our model generalization error.&lt;/p&gt;
&lt;p&gt;We can start with the following schemes to pick our model. We use
&lt;span class="math"&gt;\(d\)&lt;/span&gt; to denote the degree of polynomial of our model. For example,
&lt;span class="math"&gt;\(d = 1\)&lt;/span&gt; means &lt;span class="math"&gt;\(h_\theta(x) = \theta_0 + \theta_1 x\)&lt;/span&gt;; &lt;span class="math"&gt;\(d=2\)&lt;/span&gt; means
&lt;span class="math"&gt;\(h_\theta(x) = \theta_0 + \theta_1 x + \theta_2 x^2\)&lt;/span&gt;. Then, we can do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Optimize the parameters in &lt;span class="math"&gt;\(\Theta\)&lt;/span&gt; using the training set for each polynomial
degree &lt;span class="math"&gt;\(d\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Find the polynomial degree &lt;span class="math"&gt;\(d\)&lt;/span&gt; with the least error &lt;span class="math"&gt;\(J_\text{test}(\theta)\)&lt;/span&gt;
using the test set. We pick the model with this &lt;span class="math"&gt;\(d\)&lt;/span&gt; and report our
test set error &lt;span class="math"&gt;\(J_\text{test}(\theta)\)&lt;/span&gt; as the metric for estimate of generalization error.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;However, there is a problem with this scheme: we use our extra parameter &lt;span class="math"&gt;\(d\)&lt;/span&gt; to fit
the test set. In other words, we choose &lt;span class="math"&gt;\(d\)&lt;/span&gt;, then we fit with &lt;span class="math"&gt;\(J_\text{test}(\theta)\)&lt;/span&gt;.
Our estimate is likely optimistic and our model is likely do better on test set 
than on new examples hasn’t seen before. This is similar to overfitting in training set.&lt;/p&gt;
&lt;p&gt;In order to fix this problem, we introduce &lt;strong&gt;cross validation set&lt;/strong&gt;. We modify
above scheme as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Optimize the parameters in &lt;span class="math"&gt;\(\Theta\)&lt;/span&gt; using the training set for each polynomial degree&lt;/li&gt;
&lt;li&gt;Find the polynomial degree &lt;span class="math"&gt;\(d\)&lt;/span&gt; with the least error using the cross validation set&lt;/li&gt;
&lt;li&gt;Estimate the generalization error using the test set with &lt;span class="math"&gt;\(J_\text{test}(\theta^{(d)})\)&lt;/span&gt;
(&lt;span class="math"&gt;\(\theta^{(d)}\)&lt;/span&gt; is the parameter &lt;span class="math"&gt;\(\Theta\)&lt;/span&gt; from polynomial with the lowest error)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This way, our &lt;span class="math"&gt;\(d\)&lt;/span&gt; has not been trained using the test set. &lt;/p&gt;
&lt;h3 id="diagnosing-bias-vs-variance-which-is-which"&gt;Diagnosing bias vs. variance: which is which?&lt;/h3&gt;
&lt;p&gt;Once we have the metrics and the understanding of cross validation set, we can
now find out whether bias or variance is the problem contributing to bad predictions. 
We have the following picture to help us understand the relationship bewtween &lt;span class="math"&gt;\(d\)&lt;/span&gt;
and the underfitting (high bias) or overfitting (high variance) of our hypothesis&lt;/p&gt;
&lt;p&gt;&lt;img alt="bias vs. variance" class="img-responsive" src="https://zhu45.org/images/bias-variance.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;The training error will tend to decrease as we increase the degree &lt;span class="math"&gt;\(d\)&lt;/span&gt; of polynomial
because our hypothesis fitness to our training data becomes better and better. 
On the other hand, the cross validation error will tend to decrease
as we increase &lt;span class="math"&gt;\(d\)&lt;/span&gt; up to a point (because our model can generalize well), and
then it will increase as &lt;span class="math"&gt;\(d\)&lt;/span&gt; increased (because we now overfit the training data and
cannot be generalize well in cross validation set), forming a convex curve.
So now, based on the picture, we can answer the question: suppose the learning algorithm is
performing less well than you were hoping (&lt;span class="math"&gt;\(J_\text{cv}(\theta)\)&lt;/span&gt; or &lt;span class="math"&gt;\(J_\text{test}(\theta)\)&lt;/span&gt; is high).
is it a bias problem or a variance problem?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;High bias (underfitting): &lt;span class="math"&gt;\(J_\text{train}(\theta)\)&lt;/span&gt; will be high; 
&lt;span class="math"&gt;\(J_\text{cv}(\theta) \approx J_\text{train}(\theta)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;High variance (overfitting): &lt;span class="math"&gt;\(J_\text{train}(\theta)\)&lt;/span&gt; will be low;
&lt;span class="math"&gt;\(J_\text{cv}(\theta) \gg J_\text{train}(\theta)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="regularization-how-to-choose-lambda"&gt;Regularization: how to choose &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;?&lt;/h3&gt;
&lt;p&gt;In the overfitting section above, we know that regularization is another way
to handle the overfitting. There is a problem with regularization method: how
do we set &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; appeard in the &lt;span class="math"&gt;\(J_\theta(x)\)&lt;/span&gt;? In general, when &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;
is large, we tend to underfit (i.e. high bias) the data and when &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; is small,
we tend to overfit (i.e. high variance). In the course, the following method
is proposed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a list of &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; (i.e. &lt;span class="math"&gt;\(\lambda = 0, 0.01, 0.02, 0.04, \dots, 10.24\)&lt;/span&gt; (multiple of 2))&lt;/li&gt;
&lt;li&gt;Create a set of models with different degrees or any other variants&lt;/li&gt;
&lt;li&gt;Iterate through &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;s and for each &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;, go through all the models
to learn some &lt;span class="math"&gt;\(\theta\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Compute the cross validation error &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; without regularization term (i.e. &lt;span class="math"&gt;\(\lambda = 0\)&lt;/span&gt;)
using the learned &lt;span class="math"&gt;\(\theta\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Select the best combo that produces the lowest error on the cross validation set&lt;/li&gt;
&lt;li&gt;Using the best combo &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; and &lt;span class="math"&gt;\(\theta\)&lt;/span&gt;, apply it on &lt;span class="math"&gt;\(J_{test}(\theta)\)&lt;/span&gt;
to see if it has a good generalization.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can also plot the Bias/Variance as a function of the regulariation parameter like below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="regualarization parameter" class="img-responsive" src="https://zhu45.org/images/regularization-bias-vairance.png"/&gt;&lt;/p&gt;
&lt;h3 id="learning-curves"&gt;Learning curves&lt;/h3&gt;
&lt;p&gt;Learning curve is a tool to help us identfy whether we are facing underfitting (i.e. high bias) 
or overfitting (i.e. high variance) problem and at the same time, gives us a way to answer the question:
Will getting more training data help us improve our learning algorithm performance? &lt;/p&gt;
&lt;p&gt;The following picture shows what learning curves look like for a linear regression (i.e. &lt;span class="math"&gt;\(h_\theta(x) = \theta_0 + \theta_1 x + \theta_2 x^2\)&lt;/span&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img alt="learning curves general" class="img-responsive" src="https://zhu45.org/images/learning-curves-general.png"/&gt;&lt;/p&gt;
&lt;p&gt;The x-axis of the learning curves is the training set size &lt;span class="math"&gt;\(m\)&lt;/span&gt; and the y-axis is the error. When &lt;span class="math"&gt;\(m\)&lt;/span&gt; is small, any hypothesis
can fit the training data perfectly, and thus our &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; is small. However, as &lt;span class="math"&gt;\(m\)&lt;/span&gt; increases, our hypothesis cannot
fit all the data, and thus &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; increases. On the other hand, when &lt;span class="math"&gt;\(m\)&lt;/span&gt; is small, our hypothesis cannot generalize
much and thus &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; tends to be high. However, as &lt;span class="math"&gt;\(m\)&lt;/span&gt; increases, the more data we have, the better hypothesis we can
get and thus our hypothesis can generalize well to new examples and &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; decreases. &lt;/p&gt;
&lt;h4 id="experience-underfitting"&gt;Experience underfitting&lt;/h4&gt;
&lt;p&gt;Now, let’s see what learning curves look like when we face underfitting (i.e. high bias) problem. For example, we try to fit our
data with hypothesis &lt;span class="math"&gt;\(h_\theta(x) = \theta_0 + \theta_1x\)&lt;/span&gt;. Now, when &lt;span class="math"&gt;\(m\)&lt;/span&gt; is small, our &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; will be small, and it
will increase as &lt;span class="math"&gt;\(m\)&lt;/span&gt; increases. After certain point, our &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; will flat out because our hypothesis is a straight line
and more data won’t help much. On the other hand, &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; will be high when &lt;span class="math"&gt;\(m\)&lt;/span&gt; small and will decrease as &lt;span class="math"&gt;\(m\)&lt;/span&gt; increases. 
Similar to &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt;, &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; will quickly flat out because number of hypothesis parameter is so small and it 
won’t generalize well as data increases. In other words, when we have high bias, the performance of &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; and &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt;
will look a lot similar. Thus, our learning curve looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="high bias learning curves" class="img-responsive" src="https://zhu45.org/images/high-bias-learning-curves.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(m\)&lt;/span&gt; is small: causes &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; to be low and &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; to be high.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(m\)&lt;/span&gt; is large: causes both &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; and &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; to be high with &lt;span class="math"&gt;\(J_{train}(\theta) \approx J_{cv}(\theta)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;From above graph we can get, if a learning algorithm is suffering from high bias, getting more training data will &lt;strong&gt;not&lt;/strong&gt;
(by itself) help much.&lt;/p&gt;
&lt;h4 id="experience-overfitting"&gt;Experience overfitting&lt;/h4&gt;
&lt;p&gt;For overfitting (i.e. high variance) problem, let’s consider a hypothesis: &lt;span class="math"&gt;\(h_\theta(x) = \theta_0 + \theta_1x + \dots + \theta_{100}x^{100}\)&lt;/span&gt; 
(and small &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;). When &lt;span class="math"&gt;\(m\)&lt;/span&gt; is small, &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; is small because we fit very small data size with very high degree polynomial.
As &lt;span class="math"&gt;\(m\)&lt;/span&gt; increases, &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; increases but not so much because with high polynomial degree, even we cannot fit the data perfectly,
our hypothesis is still pretty good with large data size. For &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt;, we have overfitting problem no matter the size of &lt;span class="math"&gt;\(m\)&lt;/span&gt;. 
Even &lt;span class="math"&gt;\(m\)&lt;/span&gt; increases may help our hypothesis generalize better, our hypothesis can still do poorly for new examples. So, the learning curves
for high variance problem looks like below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="high variance learning curves" class="img-responsive" src="https://zhu45.org/images/high-variance-learning-curves.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(m\)&lt;/span&gt; is small: &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; will be low and &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; will be high.&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(m\)&lt;/span&gt; is large: &lt;span class="math"&gt;\(J_{train}(\theta)\)&lt;/span&gt; increases with training set size and &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; continues to decrease without
levelling off. Also &lt;span class="math"&gt;\(J_{train}(\theta) &amp;lt; J_{cv}(\theta)\)&lt;/span&gt; but the difference between them remains significant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;From above graph, if we keep getting more data, &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; will keep getting down and this indicates that if a learning algorithm
is suffering from high variance, getting more training data is likely to help.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;In the learning curves, &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; can be substituted with &lt;span class="math"&gt;\(J_{test}(\theta)\)&lt;/span&gt; and the shape still holds. All in all, we really
care about the size of &lt;span class="math"&gt;\(J_{cv}(\theta)\)&lt;/span&gt; (or &lt;span class="math"&gt;\(J_{test}(\theta)\)&lt;/span&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="what-to-try-next"&gt;What to try next?&lt;/h2&gt;
&lt;p&gt;Now, we can answer the question appeard in the perface section: suppose we have implemented regularized linear regression to predict
housing prices. However, when we test our hypothesis in a new set of houses, we find that it makes unacceptablely large errors in
its prediction. What we should try next?&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;When it works?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get more training examples&lt;/td&gt;
&lt;td&gt;high variance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Try smaller sets of features&lt;/td&gt;
&lt;td&gt;high variance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Try getting additional features&lt;/td&gt;
&lt;td&gt;high variance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Try adding polynomial features (i.e. &lt;span class="math"&gt;\(x_1^{2}\)&lt;/span&gt;, &lt;span class="math"&gt;\(x_2^{2}\)&lt;/span&gt;, &lt;span class="math"&gt;\(x_1x_2\)&lt;/span&gt;)&lt;/td&gt;
&lt;td&gt;high bias&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Try decreasing &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;high bias&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Try increasing &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;high variance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This leads to model complexity effects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lower-order polynomial (low model complexity) have high bias and low variance. The model fits poorly consistently.&lt;/li&gt;
&lt;li&gt;Higher-order polynomial (high model complexity) fits training data extremely well but test data poorly. Low bias but high variance on
training data. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ideally, we should choose a model somewhere in between.&lt;/p&gt;
&lt;h2 id="neural-network-and-overfitting"&gt;Neural Network and overfitting&lt;/h2&gt;
&lt;p&gt;Underfitting and overfitting also exist in the &lt;a href="https://zhu45.org/posts/2017/May/23/andrew-ngs-ml-week-04-05/"&gt;neural network&lt;/a&gt;. When
we use “small” neural network (i.e. less hidden layers, less hidden units), we have fewer parameters and more prone
to underfitting. In the contrast, when we use “large” neural network, it’s computationally more expensive and 
more parameters means more prone to overfitting. In this case, we use &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; to address the issue.&lt;/p&gt;
&lt;p&gt;We also face the similar model selection problem like we have when working with linear regression. In the neural network
setting, that means deciding number of hidden layers we need to use in the network. Prof. Ng talks about the following
method to solve the problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We create a list of number of hidden layers&lt;/li&gt;
&lt;li&gt;For each number of hidden layers, we optimize the parameters in &lt;span class="math"&gt;\(\Theta\)&lt;/span&gt; using the training set&lt;/li&gt;
&lt;li&gt;Find the number of hidden layers with the least error using the cross validation set&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Usually, using a single hidden layer is a good starting default. We can then train our neural network
on a number of hidden layers using our cross validation set. We can then choose the one that performs the
best.&lt;/p&gt;
&lt;h2 id="error-analysis"&gt;Error analysis&lt;/h2&gt;
&lt;p&gt;Error analysis means manually examine the examples (i.e. cross validation set) that your algorithm 
made errors on and see if you spot any systematic trend in what type of examples it is making errors on.
Then, we need to try some method to see if it helps. The key point during the whole analysis is that
we need to come up some numeric evaluation, which gives a single raw number, to determine how system works.&lt;/p&gt;
&lt;p&gt;This leads to a recommended approach for handling machine learning problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start with a simple algorithm that you can implement quickly. Implement it and test it on your cross-validation set.&lt;/li&gt;
&lt;li&gt;Plot learning curves to decide if more data, more features, etc, are likely to help&lt;/li&gt;
&lt;li&gt;Perform error analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ceiling-analysis"&gt;Ceiling analysis&lt;/h2&gt;
&lt;p&gt;Ceiling analysis is helpful when we work on a machine learning system, which contains many components. Then ceiling 
analysis tries to address the question: what part of the pipeline we need to focus on to improve next? This is done
by estimating the errors due to each component. Suppose we have a image recognition system with four components:&lt;/p&gt;
&lt;div class="math"&gt;$$
\text{images} \Rightarrow \text{Text detection} \Rightarrow \text{character segmentation} \Rightarrow \text{character recognition}
$$&lt;/div&gt;
&lt;p&gt;Then, we try to decide which part of the pipeline we should spend the most time trying to improve. &lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;component&lt;/th&gt;
&lt;th&gt;Accuracy of overall system&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Overall system&lt;/td&gt;
&lt;td&gt;72%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text detection&lt;/td&gt;
&lt;td&gt;89%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Character segmentation&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Character recognition&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Before we improve some component of the system, we have a overall system accuracy of &lt;span class="math"&gt;\(72\%\)&lt;/span&gt;. Now, let’s
take text detection as an example. Let’s manually label where the text is and this will give &lt;span class="math"&gt;\(100\%\)&lt;/span&gt; accuracy
of text detection. Then, we run the rest modules, and get an overall system accuracy, which in our case is &lt;span class="math"&gt;\(89\%\)&lt;/span&gt;.
We perform the similar steps for each component. Then, we calculate the gain of system accuracy. For example,
we will get &lt;span class="math"&gt;\(17\%\)&lt;/span&gt; gain by working on text detection (i.e. &lt;span class="math"&gt;\(89\% - 72\%\)&lt;/span&gt;) and &lt;span class="math"&gt;\(1\%\)&lt;/span&gt; by working on character segmentation,
and &lt;span class="math"&gt;\(10\%\)&lt;/span&gt; by working on character recognition. As you can see, text detection will give us the largest gain, and thus
we should work on this componet next.  &lt;/p&gt;
&lt;h2 id="other-issues"&gt;Other issues&lt;/h2&gt;
&lt;p&gt;Machine learning is interesting because there probably doesn’t exist a unified way to handle different kind of data.
This means for some special data, we may need to have some special approach to handle them.&lt;/p&gt;
&lt;h3 id="error-metrics-for-skewed-classes-precision-recall"&gt;Error metrics for skewed classes: Precision &amp;amp; Recall&lt;/h3&gt;
&lt;h4 id="skew-classes"&gt;Skew classes&lt;/h4&gt;
&lt;p&gt;Consider the following example: we want to do a cancer classification using logistic regression with 
&lt;span class="math"&gt;\(y=1\)&lt;/span&gt; indicating cancer and &lt;span class="math"&gt;\(y=0\)&lt;/span&gt; otherwise. After training on the training data, we find that
we got &lt;span class="math"&gt;\(1\%\)&lt;/span&gt; error on test set (i.e. &lt;span class="math"&gt;\(99\%\)&lt;/span&gt; correct diagnoses). Can we say that our learning algorithm 
is performing well? The answer is depends. We further examine the training data and find out that
only &lt;span class="math"&gt;\(0.5\%\)&lt;/span&gt; of patients have cancer. This causes problem to our training task because we can directly
set &lt;span class="math"&gt;\(y=0\)&lt;/span&gt; for every training data and we will get only &lt;span class="math"&gt;\(0.5\%\)&lt;/span&gt; error, which is less than &lt;span class="math"&gt;\(1%\)&lt;/span&gt; in our previous 
case. However, this error is useless. This is a typical scenario of &lt;strong&gt;skew classes&lt;/strong&gt;, where the number of
possitive examples &lt;span class="math"&gt;\(\ll\)&lt;/span&gt; the number of negative examples. &lt;/p&gt;
&lt;h4 id="precision-recall"&gt;Precision &amp;amp; Recall&lt;/h4&gt;
&lt;p&gt;Rather than using classification error as a measurement to our learning algorithm performance, we 
use precision and recall instead when we deal with skewed class. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let &lt;span class="math"&gt;\(y = 1\)&lt;/span&gt; in presence of &lt;em&gt;rare class&lt;/em&gt; that we want to detect&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(\text{Precision} = \frac{\text{True positives}}{\text{# predicted positives}} = \frac{\text{True positive}}{\text{True positive}+\text{False positive}}\)&lt;/span&gt;
(i.e. of all patients where we predicted &lt;span class="math"&gt;\(y = 1\)&lt;/span&gt;, what fraction actually have cancer?)&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(\text{Recall} = \frac{\text{True positives}}{\text{# actual positives}} = \frac{\text{True positives}}{\text{True positives}+\text{False negatives}}\)&lt;/span&gt;
(i.e. of all patients that actually have cancer, what fraction did we correctly detect as having cancer?)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="precision and recall" class="img-responsive" src="https://zhu45.org/images/precision-recall.png"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If we apply this concept to the previous scenario when we set &lt;span class="math"&gt;\(y=0\)&lt;/span&gt; for each training data, then the recall will be &lt;span class="math"&gt;\(0\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;There is a tradeoff between precision and recall. Suppose we have a logistic regression: &lt;span class="math"&gt;\(0 \ge h_\theta(x) \le 1\)&lt;/span&gt; and we want to predict
&lt;span class="math"&gt;\(1\)&lt;/span&gt; if &lt;span class="math"&gt;\(h_\theta(x) \ge \text{threshold}\)&lt;/span&gt; and &lt;span class="math"&gt;\(0\)&lt;/span&gt; if &lt;span class="math"&gt;\(h_\theta(x) \le \text{threshold}\)&lt;/span&gt;. Then, how do we determine that threhold value?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Suppose we want to predict &lt;span class="math"&gt;\(y=1\)&lt;/span&gt; (i.e. cancer) only if very confident: Higher precision, lower recall (i.e. threhold = &lt;span class="math"&gt;\(0.7\)&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;Suppose we want to avoid missing too many cases of cancer (i.e. avoid false negatives): Higher recall, lower precision (i.e. threshold = &lt;span class="math"&gt;\(0.3\)&lt;/span&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can see, we cannot maintain high precision and high recall at the same time. This kind of tradeoff is dicpted in the picture below: &lt;/p&gt;
&lt;p&gt;&lt;img alt="precision and recall tradeoff" class="img-responsive" src="https://zhu45.org/images/precision-recall-tradeoff.png"/&gt;&lt;/p&gt;
&lt;h4 id="f_1-score"&gt;&lt;span class="math"&gt;\(F_1\)&lt;/span&gt; score&lt;/h4&gt;
&lt;p&gt;Now, we may ask if there is a way to choose our threshold value automatically. That’s where &lt;span class="math"&gt;\(F_1\)&lt;/span&gt; score comes from. If we use &lt;span class="math"&gt;\(P\)&lt;/span&gt; to denote
the precision and &lt;span class="math"&gt;\(R\)&lt;/span&gt; to denote recall, then our &lt;span class="math"&gt;\(F_1\)&lt;/span&gt; score is defined as follows&lt;/p&gt;
&lt;div class="math"&gt;$$
F_1 \text{ score} = 2 \frac{PR}{P+R}
$$&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(P = 0\)&lt;/span&gt; or &lt;span class="math"&gt;\(R = 0\)&lt;/span&gt;, then &lt;span class="math"&gt;\(F_1 \text{ score} = 0\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(P = 1\)&lt;/span&gt; and &lt;span class="math"&gt;\(R = 1\)&lt;/span&gt;, then &lt;span class="math"&gt;\(F_1 \text{ score} = 1\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, we can pick the threshold value by measuring &lt;span class="math"&gt;\(P\)&lt;/span&gt; and &lt;span class="math"&gt;\(R\)&lt;/span&gt; on the cross validation set and choose the value of threshold which maximizes our 
&lt;span class="math"&gt;\(F_1 \text{ score}\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="data-for-machine-learning"&gt;Data for machine learning&lt;/h3&gt;
&lt;p&gt;When we should use a very large training set? Two things need to consider before we do that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assume feature &lt;span class="math"&gt;\(x \in R^{n+1}\)&lt;/span&gt; has sufficient information to predict &lt;span class="math"&gt;\(y\)&lt;/span&gt; accurately. This can be tested by answering the question: given the input
&lt;span class="math"&gt;\(x\)&lt;/span&gt;, can a human expert confidently predict &lt;span class="math"&gt;\(y\)&lt;/span&gt;?&lt;/li&gt;
&lt;li&gt;Use a learning algorithm with many parameters (i.e. logistic regression or linear regression with many features; neural network with many hidden units),
which can give us a low bias algorithm.&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Machine Learning"></category><category term="machine learning"></category><category term="coursera"></category><category term="neural network"></category></entry><entry><title>Virtual methods and polymorphism in C++</title><link href="https://zhu45.org/posts/2017/Jul/12/virtual-methods-and-polymorphism-in-c/" rel="alternate"></link><published>2017-07-12T23:11:00+08:00</published><updated>2017-07-12T23:11:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-07-12:/posts/2017/Jul/12/virtual-methods-and-polymorphism-in-c/</id><summary type="html">&lt;p&gt;virtual, pure virtual, constructors, abstract base class&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#virtual-methods"&gt;Virtual methods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#pure-virtual-function-abstract-base-class"&gt;Pure virtual function &amp;amp; abstract base class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#key-terms-summary"&gt;Key terms summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Surprisingly, even I work with the product that is written majorly in C++, I don’t have to deal
with the stuff that differentiate C++ from C. However, I’m now working on a defect that
forces me to simplify C++ objects in order to get the root cause of the problem. That’s the place
where I have to really need to know how exactly C++ class is structured. &lt;/p&gt;
&lt;p&gt;One question I asked myself several years ago: “What is virtual method in C++?” I believed, at that time,
I got the answer but I was too lazy to record it somewhere. Now, I have to pay the price by wasting my effort
again to dig out the answer. So, I’d better save it at someplace this time and the following is just
a simple example to partially show the answer to the question. I know C++ is a monster and I’ll definitely
need to rewrite the post some day in the future when I know more about the language. However, this answer
is good enough for me now.&lt;/p&gt;
&lt;h2 id="virtual-methods"&gt;Virtual methods&lt;/h2&gt;
&lt;p&gt;Let’s consider the following code snippet: we have a base class called &lt;code&gt;Animal&lt;/code&gt; and its subclass called &lt;code&gt;Dog&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getFamily&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"We are animals"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"I'm an Animal"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"I'm a Dog"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, inside the &lt;code&gt;main&lt;/code&gt;, we call &lt;code&gt;animal-&amp;gt;getClass()&lt;/code&gt; and &lt;code&gt;dog-&amp;gt;getClass()&lt;/code&gt;. We compile our code 
using &lt;code&gt;g++ -std=c++11 a.cpp&lt;/code&gt; and run the program and get&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;I'm an Animal
I'm a Dog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, each object calls their &lt;code&gt;getClass&lt;/code&gt; method respectively.
Now, let’s add a function called &lt;code&gt;whatClassAreYou()&lt;/code&gt; to our code above &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and in our &lt;code&gt;main&lt;/code&gt; function, we call our newly-added function with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and the output looks like below&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;I'm an Animal
I'm a Dog
I'm an Animal
I'm an Animal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see &lt;code&gt;whatClassAreYou()&lt;/code&gt; only calls the &lt;code&gt;getClass()&lt;/code&gt; method of our base class &lt;code&gt;Animal&lt;/code&gt; even when we pass in 
&lt;code&gt;Dog&lt;/code&gt; class object. Ideally, we want our &lt;code&gt;whatClassAreYou()&lt;/code&gt; method call the right &lt;code&gt;getClass()&lt;/code&gt; method depending on
what class object we pass into. In other words, if our &lt;code&gt;Dog&lt;/code&gt; class implements its own &lt;code&gt;getClass()&lt;/code&gt; method, we want
our &lt;code&gt;whatClassAreYou()&lt;/code&gt; method be aware of this fact and call it instead of calling &lt;code&gt;getClass()&lt;/code&gt; of our base class &lt;code&gt;Animal&lt;/code&gt;.
That’s why we want to add &lt;code&gt;virtual&lt;/code&gt; keyword to the &lt;code&gt;getClass()&lt;/code&gt; of our base class. We are essentially telling the compiler
that our base class &lt;code&gt;getClass()&lt;/code&gt; method might be overridden by its subclass and be aware of this fact when some other method
wants to call it.&lt;/p&gt;
&lt;p&gt;Now our code looks like below&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Virtual Methods and Polymorphism&lt;/span&gt;
&lt;span class="c1"&gt;// Polymorphism allows you to treat subclasses as their superclass and yet&lt;/span&gt;
&lt;span class="c1"&gt;// call the correct overwritten methods in the subclass automatically&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getFamily&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"We are animals"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// When we define a method as virtual we know that Animal&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// will be a base class that may have this method overwritten&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"I'm an Animal"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"I'm a Dog"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// use "virtual", proper getClass() method will be called depending on&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="c1"&gt;// the exact type of Animal* animal get passed in (i.e. base class Animal&lt;/span&gt;
&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="c1"&gt;// or subclass Dog)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// If a method is marked virtual or not doesn't matter if we call the&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// method directly from the object&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and the output is&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;I'm an Animal
I'm a Dog
I'm an Animal
I'm a Dog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The reason behind this scenario is what we called &lt;strong&gt;polymorphism&lt;/strong&gt;, which means “many form” in Greek. Here is how this
concept get explained in &lt;a href="https://www.amazon.com/Primer-5th-Stanley-B-Lippman/dp/0321714113"&gt;C++ Primer&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We speak of types related by inheritance as polymorphic types, 
because we can use the “many forms” of these types while ignoring the differences among them. 
The fact that the static and dynamic types of references and pointers can differ is the cornerstone of how C++ supports polymorphism.&lt;/p&gt;
&lt;p&gt;When we call a function defined in a base class through a reference or pointer to the base class, 
we do not know the type of the object on which that member is executed. 
The object can be a base-class object or an object of a derived class. 
If the function is virtual, then the decision as to which function to run is 
delayed until run time. The version of the virtual function that is run is the 
one defined by the type of the object to which the reference is bound or to 
which the pointer points. On the other hand, calls to nonvirtual functions are 
bound at compile time. Similarly, &lt;em&gt;calls to any function (virtual or not) 
on an object are also bound at compile time&lt;/em&gt;. 
The type of an object is fixed and unvarying—there is nothing we can do to 
make the dynamic type of an object differ from its static type. 
Therefore, calls made on an object are bound at compile time to the version defined by the type of the object.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Virtuals are resolved at run time only if the call is made through a &lt;em&gt;reference&lt;/em&gt; or &lt;em&gt;pointer&lt;/em&gt;. Only in these cases is it possible for 
an object’s dynamic type to differ from its static type.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;To see the final note of the above quote, let’s take a look an example&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getFamily&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"We are animals"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"I'm an Animal"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"I'm a Dog"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;whatClassAreYou2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;whatClassAreYou&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;animal2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dog2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;whatClassAreYou2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;whatClassAreYou2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dog2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this example, we define another method &lt;code&gt;whatClassAreYou2&lt;/code&gt; calls on object instead of pointers. Now, we apply this method
to our newly created objects &lt;code&gt;animal2&lt;/code&gt; and &lt;code&gt;dog2&lt;/code&gt; and we get&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;I'm an Animal
I'm a Dog
I'm an Animal
I'm a Dog
I'm an Animal
I'm an Animal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, even we have virtual function in our base class, &lt;code&gt;whatClassAreYou2()&lt;/code&gt; invokes only the base class’s &lt;code&gt;getClass()&lt;/code&gt;
method and ignores the subclass overrides. &lt;/p&gt;
&lt;p&gt;Aside note, you may notice that we use two ways to initialize our objects. The first way is through &lt;code&gt;Animal *animal = new Animal;&lt;/code&gt;
and the second way is through &lt;code&gt;Animal animal2;&lt;/code&gt;. Initialization is quite complex in C++. These two ways are essentially the same:
we use &lt;strong&gt;default constructor&lt;/strong&gt; &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; to initialize the objects. The only difference is that the first way gives us a pointer to 
the object and the second way gives object directly. To obtain the pointer to the object, we can do &lt;code&gt;Animal *ptrAnimal = &amp;amp;animal2&lt;/code&gt;.
Another way to initialize object is through value initilialization &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// default initalized to the empty string&lt;/span&gt;
&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// value initialized to the empty string&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pi1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;// default initialized; *pi1 is undefined&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pi2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;// value initialized to 0; *pi2 is 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="pure-virtual-function-abstract-base-class"&gt;Pure virtual function &amp;amp; abstract base class&lt;/h2&gt;
&lt;p&gt;Another important concept related with &lt;strong&gt;virtual&lt;/strong&gt; is called &lt;strong&gt;pure virtual&lt;/strong&gt;. The difference between this concept
is that, as stated in wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A virtual function or virtual method is a function or method whose behavior can be overriden within an inheriting class
by a function with the same signature. A pure virtual function or pure virtual method is a virtual function that
is required to be implemented by a derived class that is not abstract.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In short, virtual function can be overriden; pure virtual function must be implemented. Let’s take a look a example&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// An abstract data type is a class that acts as the base to other classes&lt;/span&gt;
&lt;span class="c1"&gt;// They stand out because its methods are initialized with zero&lt;/span&gt;
&lt;span class="c1"&gt;// A pure virtual method must be overwritten by subclasses&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getNumWheels&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getNumDoors&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;StationWagon&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Car&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getNumWheels&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Station wagon has 4 wheels"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getNumDoors&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Station wagon has 4 doors"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;endl&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;StationWagon&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;StationWagon&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// Create a StationWagon using the abstract data type Car&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Car&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;stationWagon&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;StationWagon&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;stationWagon&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getNumWheels&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, we have a base class called &lt;code&gt;Car&lt;/code&gt; and a class that derives from the &lt;code&gt;Car&lt;/code&gt; class called &lt;code&gt;StationWagon&lt;/code&gt;.  &lt;code&gt;Car&lt;/code&gt;
is a lot similar to our &lt;code&gt;Animal&lt;/code&gt; class in the sense that both classes have methods that have keyword &lt;code&gt;virtual&lt;/code&gt;. However,
&lt;code&gt;Car&lt;/code&gt; class’s methods have &lt;code&gt;=0&lt;/code&gt;. This is exactly how we identify &lt;strong&gt;pure virtual&lt;/strong&gt;: we specify that a virtual function 
is a pure virtual by writing &lt;code&gt;=0&lt;/code&gt; in place of a function body (i.e., just before the semicolon that ends the declaration).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Unlike ordinary virtuals, a pure virtual function does not have to be defined.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;=0&lt;/code&gt; may appear only on the declaration of a virtual function in the class body.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;A class like &lt;code&gt;Car&lt;/code&gt; that contains (or inherit without overriding) a pure virtual function is an &lt;strong&gt;abstract base class&lt;/strong&gt;. An
abstract base class defines an interface for subsequent classes to override. We cannot (directly) create objects of a
type that is an abstract base class.&lt;/p&gt;
&lt;h2 id="key-terms-summary"&gt;Key terms summary&lt;/h2&gt;
&lt;p&gt;Here, I summarize terms appeard in this post as a quick index for future reference:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;virtual&lt;/strong&gt;: Member function that defines type-specific behavior. Calls to virtual made through 
a reference or pointer are resolved at run time, based on the type of the object to which the reference 
or pointer is bound.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;pure virtual&lt;/strong&gt;: Virtual function declared in the class header using &lt;code&gt;=0&lt;/code&gt; just before the semicolon. A pure
virtual function need not be (but maybe) defined. Classes with pure virtuals are abstract classes. If a 
derived class does not define its own version of an inherited pure virtual, then the derived class is abstract as well.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;polymorphism&lt;/strong&gt;: As used in object-oriented programming, refers to the ability to obtain type-specific behavior
based on the dynamic type of a reference or pointer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;static type&lt;/strong&gt;: Type with which a variable is defined or that an expression yields. Static type is known at compile time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;dynamic type&lt;/strong&gt;: Type of an object at runtime. The dynamic type of an object to which a reference refers or to which
a pointer points may differ from the static type of the reference or pointer. A pointer or reference to a base-class type
can refer to an object of derived type. In such cases the static type is reference (or pointer) to base, but 
the dynamic type is reference (or pointer) to derived.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;abstract base class&lt;/strong&gt;: Class that has one or more pure virtual functions. We cannot create objects of an 
abstract base-class type.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;See Section 7.1.4 Constructors (p.262) of C++ Primier (5th edition) for details. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;See Section 12.1.2 Managing Memory Directly (p.459) of C++ Primier (5th edition) for details. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="programming languages"></category><category term="cpp"></category></entry><entry><title>Merge sort</title><link href="https://zhu45.org/posts/2017/Jul/01/merge-sort/" rel="alternate"></link><published>2017-07-01T23:33:00+08:00</published><updated>2017-07-01T23:33:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-07-01:/posts/2017/Jul/01/merge-sort/</id><summary type="html">&lt;p&gt;summary for mergesort&lt;/p&gt;</summary><content type="html">&lt;p&gt;We continue our journey in sorting. Specifically, we’ll study
the mergesort in this post.&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;The fundamental idea in the mergesort is merging two sorted lists into one. 
Because the lists are sorted, this can be done in one pass through the input, if 
the output is put in a third list. The basic merging algorithm takes two input
arrays &lt;span class="math"&gt;\(A\)&lt;/span&gt; and &lt;span class="math"&gt;\(B\)&lt;/span&gt;, an output array &lt;span class="math"&gt;\(C\)&lt;/span&gt;, and three counters, &lt;code&gt;Aptr&lt;/code&gt;, &lt;code&gt;Bptr&lt;/code&gt;, and
&lt;code&gt;Cptr&lt;/code&gt;, which are initally set to the beginning of their respective arrays.
The smaller of &lt;code&gt;A[Aptr]&lt;/code&gt; and &lt;code&gt;B[Bptr]&lt;/code&gt; is copied to the next entry in &lt;span class="math"&gt;\(C\)&lt;/span&gt;, and
the appropriate counters are advanced. When either input list is exhausted, the 
remainder of the other list is copied to &lt;span class="math"&gt;\(C\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;The running time for merging is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;, because at most &lt;span class="math"&gt;\(N-1\)&lt;/span&gt; comparisons are made,
where &lt;span class="math"&gt;\(N\)&lt;/span&gt; is the total number of elements. To see this, note that every comparison
adds an element to &lt;span class="math"&gt;\(C\)&lt;/span&gt;, except the last comparison, which adds at least two. &lt;/p&gt;
&lt;p&gt;Once we have this idea in mind, we can now describe our mergesort algorithm:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(N=1\)&lt;/span&gt;, there is only one element to sort, and we are done.&lt;/li&gt;
&lt;li&gt;Otherwise, we recursively mergesort the first half and the second half. This gives
two sorted halves, which can then be merged together using the merging algorithm.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As you can see, our mergesort is a classic example of  divide-and-conquer strategy.
The problem is &lt;em&gt;divided&lt;/em&gt; into smaller problems and solved recursively. The &lt;em&gt;conquering&lt;/em&gt;
phase consists of patching together the answers.&lt;/p&gt;
&lt;p&gt;The mergesort algorithm can be implemented as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// start of left half&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// start of right half&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;leftEnd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numElements&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpPos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;leftEnd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tmpPos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;numElements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// main loop&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;leftEnd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tmpPos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tmpPos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;leftEnd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Copy rest of first half&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tmpPos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;lpos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Copy rest of second half&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tmpPos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rpos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numElements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// copy tmpArray back&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rightEnd&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;msort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;msort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;msort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;mergeSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;msort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that we use &lt;code&gt;tmpArray&lt;/code&gt; working as array &lt;span class="math"&gt;\(C\)&lt;/span&gt; in our merging algorithm
to hold the merge result from our two input sorted arrays. One naive implementation
is that we declare a temporary array locally each time we call &lt;code&gt;Merge&lt;/code&gt;. This can
be problematic because there could be &lt;span class="math"&gt;\(\log N\)&lt;/span&gt; temporary arrays active at any point.
This could be fatal on a machine with small memory and at the same time, we will
spend quite a lot time calling &lt;code&gt;malloc&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;The trick for our implementation is that we declare a global temporary array
&lt;code&gt;tmpArray&lt;/code&gt; of size &lt;span class="math"&gt;\(N\)&lt;/span&gt; at the very beginning. Then, we use &lt;code&gt;lpos&lt;/code&gt;, &lt;code&gt;rpos&lt;/code&gt;, &lt;code&gt;rightEnd&lt;/code&gt;
to control the fraction of &lt;code&gt;tmpArray&lt;/code&gt; will be used for merge step. This is a common
implementation trick, which will visit again immediately.&lt;/p&gt;
&lt;p&gt;Like many other recursive algorithm, mergesort can also be implemented as
non-recursive algorithm as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;mergeSortNonRecursive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part1Start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part2Start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part2End&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;part1Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;part1Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;part2Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part1Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;part2End&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part2Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;subListSize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part1Start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part2Start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part2End&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;part1Start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part2End&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s take a look at an example for better understanding of the implementation
above. Suppose we want to sort the following list using mergesort: 
&lt;span class="math"&gt;\(31, 41, 59, 26, 53, 58, 97\)&lt;/span&gt;. We start from very basic case: merge two sorted
list of one element, into a sorted list of two elements. For example,
&lt;code&gt;part1Start = 0&lt;/code&gt;, &lt;code&gt;part2Start = 1&lt;/code&gt;, &lt;code&gt;part2End = 1&lt;/code&gt; for the first iteration
of while loop when &lt;code&gt;subListSize = 1&lt;/code&gt;. Then, we call &lt;code&gt;merge&lt;/code&gt; function and
use the fraction of &lt;code&gt;tmpArray&lt;/code&gt; from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; to hold the merge result.
We can print out the value &lt;code&gt;part1Start&lt;/code&gt;, &lt;code&gt;part2Start&lt;/code&gt;, and &lt;code&gt;part2End&lt;/code&gt; to help
us better understand the flow of the program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Before mergeSort: 31, 41, 59, 26, 53, 58, 97,
part1Start: 0
part2Start: 1
part2End: 1
part1Start: 2
part2Start: 3
part2End: 3
part1Start: 4
part2Start: 5
part2End: 5
part1Start: 0
part2Start: 2
part2End: 3
part1Start: 0
part2Start: 4
part2End: 6
After mergeSort: 26, 31, 41, 53, 58, 59, 97,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="analysis"&gt;Analysis&lt;/h2&gt;
&lt;p&gt;The running time of mergesort is &lt;span class="math"&gt;\(O(N \log N)\)&lt;/span&gt;, which can be obtained
by &lt;a href="https://zhu45.org/posts/2017/Jun/12/solving-recurrence-relations-part-2/"&gt;solving the recurrence relation&lt;/a&gt;:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*} 
T(1) &amp;amp;=&amp;amp; 1 \\
T(N) &amp;amp;=&amp;amp; 2T(N/2) + N 
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;One thing to notice that we assume &lt;span class="math"&gt;\(N = 2^k\)&lt;/span&gt; when solve the above recurrence relation.
The answer is almost identical even if &lt;span class="math"&gt;\(N\)&lt;/span&gt; is not a power of &lt;span class="math"&gt;\(2\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="final-remarks"&gt;Final remarks&lt;/h2&gt;
&lt;p&gt;We hardly use mergesort for main memory sorts. The main problem is that merging two
sorted lists requires linear extra memory, and the additional work spent coping to the temporary
array and back, throughout the algorithm, has the effect of slowing down the sort considerably.
Thus, for serious internal sorting applications, we use quicksort instead.
Nevertheless, the merging routine is the cornerstone of most external sorting algorithms.&lt;/p&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MAW Chapter 7&lt;/li&gt;
&lt;/ol&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="sorting"></category><category term="maw"></category></entry><entry><title>join in SQL</title><link href="https://zhu45.org/posts/2017/Jun/23/join-in-sql/" rel="alternate"></link><published>2017-06-23T21:23:00+08:00</published><updated>2017-06-23T21:23:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-06-23:/posts/2017/Jun/23/join-in-sql/</id><summary type="html">&lt;p&gt;A study on join statement in SQL&lt;/p&gt;</summary><content type="html">&lt;p&gt;In this post, I’ll provide a summary on the usage of &lt;code&gt;join&lt;/code&gt; statement in SQL
and use &lt;a href="https://leetcode.com/problems/combine-two-tables/"&gt;Leetcode 175&lt;/a&gt; as 
a concrete example to show several equivalent &lt;code&gt;join&lt;/code&gt; statement usage.&lt;/p&gt;
&lt;p&gt;To be honest, this is my third time visiting this material. The very first time
happened when I took DB course in college, and the second time was when I joined
the federation team at IBM and learned about DB2. Unfortunately, I didn’t keep
my study notes well in the first two tries and I don’t write SQL a lot during my
day to day work. Things, again, get rusty very quickly. This time I want to do a
better job by, at least, saving my notes in a good place &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;1&lt;/a&gt;&lt;/sup&gt;. &lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#summary"&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#motivation"&gt;Motivation&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#cartesian-product"&gt;Cartesian product&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#join"&gt;join&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#sql-perspective"&gt;SQL perspective&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#inner-join"&gt;inner join&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#natural-join"&gt;natural join&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#join-using"&gt;join … using&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#join-on"&gt;join … on&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#outer-join"&gt;outer join&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#motivation_1"&gt;Motivation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#outer-join_1"&gt;outer join&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#relational-algebra-perspective"&gt;Relational algebra perspective&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#examples"&gt;Examples&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#leetcode-175"&gt;Leetcode 175&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#example-two"&gt;Example Two&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#links-to-resources"&gt;Links to resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;natural join&lt;/code&gt; produces a relation from two relations by considering only those pairs of tuples
with the same value on those attributes that appear in the schemas of both relations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;join ... using&lt;/code&gt; specifies a subset of common attributes to join.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;join ... on&lt;/code&gt; specifies a predicate to use on join.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;outer join&lt;/code&gt; is used when we want to preserve the tuples that may have null value on
the common attributes of either or both of the relations that we want to join on.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Before we directly jump into the SQL, I want to briefly talks about the motivation
for the &lt;code&gt;join&lt;/code&gt; statement. Specifically, why do we need it? In short, &lt;code&gt;join&lt;/code&gt; is used
as a shorthand for a widely-used type of query where we want to equate two columns
in two tables in the &lt;code&gt;where&lt;/code&gt; clause (e.g., &lt;code&gt;T1.a = T2.a&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;To retrieve data from multiple relations (i.e. more than one table), we can either
use a cartesian product or join of columns of the same data type.&lt;/p&gt;
&lt;h3 id="cartesian-product"&gt;Cartesian product&lt;/h3&gt;
&lt;p&gt;The cartesian product happens to the relations listed in the &lt;code&gt;from&lt;/code&gt; clause of a SQL.
The end result of cartesian product is a relation that has all attributes from
all the relations in the &lt;code&gt;from&lt;/code&gt; clause. The following iterative process shows
how the cartesian product of the relations in the &lt;code&gt;from&lt;/code&gt; clause get generated&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tuple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;relation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;r1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tuple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;relation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;r2&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;.
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tuple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;relation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;rm&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;Concatenate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t1&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t2&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;single&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tuple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;Add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;relation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another perspective to understand cartesian product is from relation algebra cross-product
&lt;span class="math"&gt;\(R \times S\)&lt;/span&gt;, which is defined as: returns a relation instance whose schema
contains all the fields of &lt;span class="math"&gt;\(R\)&lt;/span&gt; (in the same order as they appear in &lt;span class="math"&gt;\(R\)&lt;/span&gt;) followed 
by all the fields of &lt;span class="math"&gt;\(S\)&lt;/span&gt; (in the same order as they appear in &lt;span class="math"&gt;\(S\)&lt;/span&gt;). The result of
&lt;span class="math"&gt;\(R \times S\)&lt;/span&gt; contains all tuples &lt;span class="math"&gt;\((r,s)\)&lt;/span&gt; (the concatenation of tuples &lt;span class="math"&gt;\(r\)&lt;/span&gt; and &lt;span class="math"&gt;\(s\)&lt;/span&gt;)
for each pair of tuples &lt;span class="math"&gt;\(r \in R\)&lt;/span&gt;, &lt;span class="math"&gt;\(s \in S\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To see a concrete example, let’s consider the following SQL&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;teaches&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instructor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;em&gt;teaches&lt;/em&gt; and &lt;em&gt;instructor&lt;/em&gt; table look like below&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select &lt;span class="gs"&gt;* from teaches;&lt;/span&gt;
&lt;span class="gs"&gt;ID|course_id|sec_id|semester|year&lt;/span&gt;
&lt;span class="gs"&gt;10101|CS-101|1|Fall|2009&lt;/span&gt;
&lt;span class="gs"&gt;10101|CS-315|1|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;10101|CS-347|1|Fall|2009&lt;/span&gt;
&lt;span class="gs"&gt;12121|FIN-201|1|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;15151|MU-199|1|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;22222|PHY-101|1|Fall|2009&lt;/span&gt;
&lt;span class="gs"&gt;32343|HIS-351|1|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;45565|CS-101|1|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;45565|CS-319|1|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;76766|BIO-101|1|Summer|2009&lt;/span&gt;
&lt;span class="gs"&gt;76766|BIO-301|1|Summer|2010&lt;/span&gt;
&lt;span class="gs"&gt;83821|CS-190|1|Spring|2009&lt;/span&gt;
&lt;span class="gs"&gt;83821|CS-190|2|Spring|2009&lt;/span&gt;
&lt;span class="gs"&gt;83821|CS-319|2|Spring|2010&lt;/span&gt;
&lt;span class="gs"&gt;98345|EE-181|1|Spring|2009&lt;/span&gt;

&lt;span class="gs"&gt;sqlite&amp;gt; select *&lt;/span&gt; from instructor;
ID|name|dept_name|salary
10101|Srinivasan|Comp. Sci.|65000
12121|Wu|Finance|90000
15151|Mozart|Music|40000
22222|Einstein|Physics|95000
32343|El Said|History|60000
33456|Gold|Physics|87000
45565|Katz|Comp. Sci.|75000
58583|Califieri|History|62000
76543|Singh|Finance|80000
76766|Crick|Biology|72000
83821|Brandt|Comp. Sci.|92000
98345|Kim|Elec. Eng.|80000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;teaches&lt;/em&gt; table has 15 rows; &lt;em&gt;instructor&lt;/em&gt; table
has 12 rows. Then, if we run our SQL above, we get our result looks like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from instructor, teaches limit 20;
ID|name|dept_name|salary|ID|course_id|sec_id|semester|year
10101|Srinivasan|Comp. Sci.|65000|10101|CS-101|1|Fall|2009
10101|Srinivasan|Comp. Sci.|65000|10101|CS-315|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|10101|CS-347|1|Fall|2009
10101|Srinivasan|Comp. Sci.|65000|12121|FIN-201|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|15151|MU-199|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|22222|PHY-101|1|Fall|2009
10101|Srinivasan|Comp. Sci.|65000|32343|HIS-351|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|45565|CS-101|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|45565|CS-319|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|76766|BIO-101|1|Summer|2009
10101|Srinivasan|Comp. Sci.|65000|76766|BIO-301|1|Summer|2010
10101|Srinivasan|Comp. Sci.|65000|83821|CS-190|1|Spring|2009
10101|Srinivasan|Comp. Sci.|65000|83821|CS-190|2|Spring|2009
10101|Srinivasan|Comp. Sci.|65000|83821|CS-319|2|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|98345|EE-181|1|Spring|2009
12121|Wu|Finance|90000|10101|CS-101|1|Fall|2009
12121|Wu|Finance|90000|10101|CS-315|1|Spring|2010
12121|Wu|Finance|90000|10101|CS-347|1|Fall|2009
12121|Wu|Finance|90000|12121|FIN-201|1|Spring|2010
12121|Wu|Finance|90000|15151|MU-199|1|Spring|2010
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The result relation has 180 rows, which exactly equal to &lt;span class="math"&gt;\(12 \times 15\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;Quite often, we use &lt;code&gt;where&lt;/code&gt; clause to restrict the combinations created by the 
cartesian product to those that are meaningful for the desired answer. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instructor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;teaches&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;teaches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this query, we combine information from the &lt;em&gt;instructor&lt;/em&gt; and &lt;em&gt;teaches&lt;/em&gt; table
and the matching condition requires &lt;code&gt;instructor.ID&lt;/code&gt; to be equal to &lt;code&gt;teaches.ID&lt;/code&gt;. 
In fact, these are the only attributes in the two relations that have the same name. 
&lt;em&gt;In general, we may often find us writing SQLs that requires all attributes with matching names to be equated in the &lt;code&gt;where&lt;/code&gt; clause. This case is so common that we use &lt;code&gt;join&lt;/code&gt; to save us some effort.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="join"&gt;join&lt;/h2&gt;
&lt;p&gt;In this section, I’ll talk about &lt;code&gt;join&lt;/code&gt; from SQL perspective, and then I’ll also
present how &lt;code&gt;join&lt;/code&gt; is actually defined in relational algebra.&lt;/p&gt;
&lt;h3 id="sql-perspective"&gt;SQL perspective&lt;/h3&gt;
&lt;p&gt;There are two basic types of join: &lt;strong&gt;inner join&lt;/strong&gt; and &lt;strong&gt;outer join&lt;/strong&gt;. &lt;strong&gt;inner&lt;/strong&gt; keyword
is optional. In other words, if only &lt;code&gt;join&lt;/code&gt; appears in the SQL statement, we usually
assume it to be &lt;strong&gt;inner join&lt;/strong&gt;. Under &lt;strong&gt;outer join&lt;/strong&gt;, we can further specify whether
it is &lt;strong&gt;left outer join&lt;/strong&gt;, &lt;strong&gt;right outer join&lt;/strong&gt;, or &lt;strong&gt;full outer join&lt;/strong&gt;. Here 
is a graphic summary for the text above&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;- (inner) join
- outer join
   |- left outer join
   |- right outer join
   |- full outer join
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In addition, there are join conditions that we can use in combination with
the join form mentioned above. Any form of join (inner, left outer,
right outer, or full outer) can be combined with any join condition (natural, using, or on).
The table below provides a summary of join types and join conditions&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Join types&lt;/th&gt;
&lt;th&gt;Join conditions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;inner join&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;natural&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;left outer join&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;on &lt;predicate&gt;&lt;/predicate&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;right outer join&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;using (&lt;span class="math"&gt;\(A_1, A_2, \dots, A_n\)&lt;/span&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;full outer join&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Then the SQL syntax is &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;natural&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;table2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id="inner-join"&gt;inner join&lt;/h4&gt;
&lt;h5 id="natural-join"&gt;natural join&lt;/h5&gt;
&lt;p&gt;We start this section by considering &lt;strong&gt;natural join&lt;/strong&gt;. The natural join works
on two relations and produces a relation as the result. Unlike the cartesian
product of two relations, which concatenates each tuple of the first relation
with every tuple of the second, natural join considers only those pairs of tuples
with the same value on those attributes that appear in the schemas of both relations.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;teaches&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Consider the query above, computing &lt;code&gt;instructor natural join teaches&lt;/code&gt; considers
only those pairs of tuples where both the tuple from &lt;code&gt;instructor&lt;/code&gt; and the tuple
from &lt;code&gt;teaches&lt;/code&gt; have the same value on the common attribute, &lt;code&gt;ID&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from instructor natural join teaches;
ID|name|dept_name|salary|course_id|sec_id|semester|year
10101|Srinivasan|Comp. Sci.|65000|CS-101|1|Fall|2009
10101|Srinivasan|Comp. Sci.|65000|CS-315|1|Spring|2010
10101|Srinivasan|Comp. Sci.|65000|CS-347|1|Fall|2009
12121|Wu|Finance|90000|FIN-201|1|Spring|2010
15151|Mozart|Music|40000|MU-199|1|Spring|2010
22222|Einstein|Physics|95000|PHY-101|1|Fall|2009
32343|El Said|History|60000|HIS-351|1|Spring|2010
45565|Katz|Comp. Sci.|75000|CS-101|1|Spring|2010
45565|Katz|Comp. Sci.|75000|CS-319|1|Spring|2010
76766|Crick|Biology|72000|BIO-101|1|Summer|2009
76766|Crick|Biology|72000|BIO-301|1|Summer|2010
83821|Brandt|Comp. Sci.|92000|CS-190|1|Spring|2009
83821|Brandt|Comp. Sci.|92000|CS-190|2|Spring|2009
83821|Brandt|Comp. Sci.|92000|CS-319|2|Spring|2010
98345|Kim|Elec. Eng.|80000|EE-181|1|Spring|2009
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since &lt;code&gt;join&lt;/code&gt; is really a shorthand of writing a type of SQL with cartesian product, we can get the same 
result using &lt;code&gt;select * from instructor, teaches where instructor.ID = teaches.ID;&lt;/code&gt;. From above query result we can see that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;We do not repeat those attributes that appear in the schemas of both relations;
rather they appear only once (e.g. only one &lt;code&gt;ID&lt;/code&gt; column, not two).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The order in which the attributes are listed: first the attributes common to the schemas
of both relations, second those attributes unqiue to the schema of the first relation, and
finally, those attribute unique to the schema of the second relation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All the columns from &lt;code&gt;instructor&lt;/code&gt; table (4 columns) and &lt;code&gt;teaches&lt;/code&gt; (5 columns) table show up in the final result (8 columns in total except &lt;code&gt;ID&lt;/code&gt; column showing up once).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition, natural join will consider ALL the attributes that appear in the 
schemas of both relations. Consider the following query&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;teaches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;course&lt;/em&gt; table looks like the following&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from course;
course_id|title|dept_name|credits
BIO-101|Intro. to Biology|Biology|4
BIO-301|Genetics|Biology|4
BIO-399|Computational Biology|Biology|3
CS-101|Intro. to Computer Science|Comp. Sci.|4
CS-190|Game Design|Comp. Sci.|4
CS-315|Robotics|Comp. Sci.|3
CS-319|Image Processing|Comp. Sci.|3
CS-347|Database System Concepts|Comp. Sci.|3
EE-181|Intro. to Digital Systems|Elec. Eng.|3
FIN-201|Investment Banking|Finance|3
HIS-351|World History|History|3
MU-199|Music Video Production|Music|3
PHY-101|Physical Principles|Physics|4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;instructor&lt;/code&gt; has attributes (&lt;code&gt;ID|name|dept_name|salary&lt;/code&gt;); 
&lt;code&gt;teaches&lt;/code&gt; has attributes (&lt;code&gt;ID|course_id|sec_id|semester|year&lt;/code&gt;);
&lt;code&gt;course&lt;/code&gt; has attributes (&lt;code&gt;course_id|title|dept_name|credits&lt;/code&gt;). The first &lt;code&gt;natural join&lt;/code&gt;
will first do cartesian product of &lt;code&gt;instructor&lt;/code&gt; and &lt;code&gt;teaches&lt;/code&gt; and 
keep the tuples that have the same value on &lt;code&gt;ID&lt;/code&gt;. Then, the resulting relation
will do the second &lt;code&gt;natural join&lt;/code&gt; with &lt;code&gt;course&lt;/code&gt; and 
will keep the tuples that have the same value on &lt;code&gt;course_id&lt;/code&gt; and &lt;code&gt;dept_name&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from instructor natural join teaches natural join course;
ID|name|dept_name|salary|course_id|sec_id|semester|year|title|credits
10101|Srinivasan|Comp. Sci.|65000|CS-101|1|Fall|2009|Intro. to Computer Science|4
10101|Srinivasan|Comp. Sci.|65000|CS-315|1|Spring|2010|Robotics|3
10101|Srinivasan|Comp. Sci.|65000|CS-347|1|Fall|2009|Database System Concepts|3
12121|Wu|Finance|90000|FIN-201|1|Spring|2010|Investment Banking|3
15151|Mozart|Music|40000|MU-199|1|Spring|2010|Music Video Production|3
22222|Einstein|Physics|95000|PHY-101|1|Fall|2009|Physical Principles|4
32343|El Said|History|60000|HIS-351|1|Spring|2010|World History|3
45565|Katz|Comp. Sci.|75000|CS-101|1|Spring|2010|Intro. to Computer Science|4
45565|Katz|Comp. Sci.|75000|CS-319|1|Spring|2010|Image Processing|3
76766|Crick|Biology|72000|BIO-101|1|Summer|2009|Intro. to Biology|4
76766|Crick|Biology|72000|BIO-301|1|Summer|2010|Genetics|4
83821|Brandt|Comp. Sci.|92000|CS-190|1|Spring|2009|Game Design|4
83821|Brandt|Comp. Sci.|92000|CS-190|2|Spring|2009|Game Design|4
83821|Brandt|Comp. Sci.|92000|CS-319|2|Spring|2010|Image Processing|3
98345|Kim|Elec. Eng.|80000|EE-181|1|Spring|2009|Intro. to Digital Systems|3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h5 id="join-using"&gt;join … using&lt;/h5&gt;
&lt;p&gt;Automatically equate all the attributes with the same name from both schemas of 
relations may be too strong. Quite often, we may want to do &lt;code&gt;natural join&lt;/code&gt; on 
specific subsets of the common-shared attributes. This leads to our join condition
grammar: &lt;code&gt;join ... using (&lt;/code&gt;&lt;span class="math"&gt;\(A_1, A_2, \dots, A_n\)&lt;/span&gt;&lt;code&gt;)&lt;/code&gt;. The operation requires 
a list of attribute names to be specified. Both inputs must have attributes with the specified
names. Consider the operation &lt;span class="math"&gt;\(r_1\)&lt;/span&gt; &lt;code&gt;join&lt;/code&gt; &lt;span class="math"&gt;\(r_2\)&lt;/span&gt; &lt;code&gt;using (&lt;/code&gt; &lt;span class="math"&gt;\(A_1, A_2\)&lt;/span&gt; &lt;code&gt;)&lt;/code&gt;. The operation
is similar to &lt;span class="math"&gt;\(r_1\)&lt;/span&gt; &lt;code&gt;natural join&lt;/code&gt; &lt;span class="math"&gt;\(r_2\)&lt;/span&gt;, execpt that a pair of tuples &lt;span class="math"&gt;\(t_1\)&lt;/span&gt; from
&lt;span class="math"&gt;\(r_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(t_2\)&lt;/span&gt; from &lt;span class="math"&gt;\(r_2\)&lt;/span&gt; match if &lt;span class="math"&gt;\(t_1.A_1 = t_2.A_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(t_1.A_2 = t_2.A_2\)&lt;/span&gt;;
even if &lt;span class="math"&gt;\(r_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(r_2\)&lt;/span&gt; both have an attribute named &lt;span class="math"&gt;\(A_3\)&lt;/span&gt;, it is &lt;em&gt;not&lt;/em&gt; required
that &lt;span class="math"&gt;\(t_1.A_3 = t_2.A_3\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;An example query look like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instructor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;teaches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;course&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h5 id="join-on"&gt;join … on&lt;/h5&gt;
&lt;p&gt;Another form of join condition is the &lt;strong&gt;on&lt;/strong&gt; condition, which allows a general 
predicate over the relations being joined. The predicte is written like a &lt;strong&gt;where&lt;/strong&gt;
clause predicate except for the use of the keyword &lt;strong&gt;on&lt;/strong&gt; rahter than &lt;strong&gt;where&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, the below two queries are equivalent with each other (i.e. gives the 
same result)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The query is almost the same as using &lt;code&gt;student natural join takes&lt;/code&gt;, except that
the “ID” columns twices in the result set. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;One question we may ask is why do we need this &lt;strong&gt;on&lt;/strong&gt; operation if it may look
like working exactly the same as &lt;strong&gt;where&lt;/strong&gt; clause? The answer is&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;on&lt;/strong&gt; conditions behaves different from &lt;strong&gt;where&lt;/strong&gt; conditions when we work with
&lt;strong&gt;outer join&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SQL query is often more readable by humans if the join condition is specified in the 
&lt;strong&gt;on&lt;/strong&gt; clause and the rest of the conditions appear in the &lt;strong&gt;where&lt;/strong&gt; clause. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="outer-join"&gt;outer join&lt;/h4&gt;
&lt;h5 id="motivation_1"&gt;Motivation&lt;/h5&gt;
&lt;p&gt;Let’s consider &lt;code&gt;student&lt;/code&gt; and &lt;code&gt;takes&lt;/code&gt; tables look like the below&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select &lt;span class="gs"&gt;* from student;&lt;/span&gt;
&lt;span class="gs"&gt;ID|name|dept_name|tot_cred&lt;/span&gt;
&lt;span class="gs"&gt;00128|Zhang|Comp. Sci.|102&lt;/span&gt;
&lt;span class="gs"&gt;12345|Shankar|Comp. Sci.|32&lt;/span&gt;
&lt;span class="gs"&gt;19991|Brandt|History|80&lt;/span&gt;
&lt;span class="gs"&gt;23121|Chavez|Finance|110&lt;/span&gt;
&lt;span class="gs"&gt;44553|Peltier|Physics|56&lt;/span&gt;
&lt;span class="gs"&gt;45678|Levy|Physics|46&lt;/span&gt;
&lt;span class="gs"&gt;54321|Williams|Comp. Sci.|54&lt;/span&gt;
&lt;span class="gs"&gt;55739|Sanchez|Music|38&lt;/span&gt;
&lt;span class="gs"&gt;70557|Snow|Physics|0&lt;/span&gt;
&lt;span class="gs"&gt;76543|Brown|Comp. Sci.|58&lt;/span&gt;
&lt;span class="gs"&gt;76653|Aoi|Elec. Eng.|60&lt;/span&gt;
&lt;span class="gs"&gt;98765|Bourikas|Elec. Eng.|98&lt;/span&gt;
&lt;span class="gs"&gt;98988|Tanaka|Biology|120&lt;/span&gt;

&lt;span class="gs"&gt;sqlite&amp;gt; select *&lt;/span&gt; from takes;
ID|course_id|sec_id|semester|year|grade
00128|CS-101|1|Fall|2009|A
00128|CS-347|1|Fall|2009|A-
12345|CS-101|1|Fall|2009|C
12345|CS-190|2|Spring|2009|A
12345|CS-315|1|Spring|2010|A
12345|CS-347|1|Fall|2009|A
19991|HIS-351|1|Spring|2010|B
23121|FIN-201|1|Spring|2010|C+
44553|PHY-101|1|Fall|2009|B-
45678|CS-101|1|Fall|2009|F
45678|CS-101|1|Spring|2010|B+
45678|CS-319|1|Spring|2010|B
54321|CS-101|1|Fall|2009|A-
54321|CS-190|2|Spring|2009|B+
55739|MU-199|1|Spring|2010|A-
76543|CS-101|1|Fall|2009|A
76543|CS-319|2|Spring|2010|A
76653|EE-181|1|Spring|2009|C
98765|CS-101|1|Fall|2009|C-
98765|CS-315|1|Spring|2010|B
98988|BIO-101|1|Summer|2009|A
98988|BIO-301|1|Summer|2010|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Suppose we wish to display a list of all students along with the courses they have
taken. We come up a query that looks like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This query actually is not right for our purpose because it will not show
the student who takes no course. This is because his &lt;code&gt;ID&lt;/code&gt; will only appear
in &lt;code&gt;student&lt;/code&gt; table not in &lt;code&gt;takes&lt;/code&gt; table. If we do &lt;code&gt;natural join&lt;/code&gt;, the value
of &lt;code&gt;ID&lt;/code&gt; will not equal (one is a number and the other is null), which will
not show up in our final result set. Example in our case will be student Snow
with &lt;code&gt;ID&lt;/code&gt; 70557, who has not taken any course. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from student natural join takes;
ID|name|dept_name|tot_cred|course_id|sec_id|semester|year|grade
00128|Zhang|Comp. Sci.|102|CS-101|1|Fall|2009|A
00128|Zhang|Comp. Sci.|102|CS-347|1|Fall|2009|A-
12345|Shankar|Comp. Sci.|32|CS-101|1|Fall|2009|C
12345|Shankar|Comp. Sci.|32|CS-190|2|Spring|2009|A
12345|Shankar|Comp. Sci.|32|CS-315|1|Spring|2010|A
12345|Shankar|Comp. Sci.|32|CS-347|1|Fall|2009|A
19991|Brandt|History|80|HIS-351|1|Spring|2010|B
23121|Chavez|Finance|110|FIN-201|1|Spring|2010|C+
44553|Peltier|Physics|56|PHY-101|1|Fall|2009|B-
45678|Levy|Physics|46|CS-101|1|Fall|2009|F
45678|Levy|Physics|46|CS-101|1|Spring|2010|B+
45678|Levy|Physics|46|CS-319|1|Spring|2010|B
54321|Williams|Comp. Sci.|54|CS-101|1|Fall|2009|A-
54321|Williams|Comp. Sci.|54|CS-190|2|Spring|2009|B+
55739|Sanchez|Music|38|MU-199|1|Spring|2010|A-
76543|Brown|Comp. Sci.|58|CS-101|1|Fall|2009|A
76543|Brown|Comp. Sci.|58|CS-319|2|Spring|2010|A
76653|Aoi|Elec. Eng.|60|EE-181|1|Spring|2009|C
98765|Bourikas|Elec. Eng.|98|CS-101|1|Fall|2009|C-
98765|Bourikas|Elec. Eng.|98|CS-315|1|Spring|2010|B
98988|Tanaka|Biology|120|BIO-101|1|Summer|2009|A
98988|Tanaka|Biology|120|BIO-301|1|Summer|2010|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;More generally, some tuples in either or both of the relations being joined 
may be “lost” in this way. The &lt;strong&gt;outer join&lt;/strong&gt; operation works in a manner similar
to the join operations we studied above, but preserve those tuples that would be
lost in a join, by creating tuples in the result containing null values.&lt;/p&gt;
&lt;h5 id="outer-join_1"&gt;outer join&lt;/h5&gt;
&lt;p&gt;There are three forms of outer join:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;left outer join&lt;/strong&gt; preserves tuples only in the relation named before
(to the left of) the &lt;code&gt;left outer join&lt;/code&gt; operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;right outer join&lt;/strong&gt; preserves tuples only in the relation named after
(to the right of) the &lt;code&gt;right outer join&lt;/code&gt; operation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;full outer join&lt;/strong&gt; preserves tuples in both relations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For our example, the actual query should be&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;which returns result that includes student Snow with nulls for the
attributes that appear only in the schema of the &lt;em&gt;take&lt;/em&gt; relation&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from student natural left outer join takes;
ID|name|dept_name|tot_cred|course_id|sec_id|semester|year|grade
00128|Zhang|Comp. Sci.|102|CS-101|1|Fall|2009|A
00128|Zhang|Comp. Sci.|102|CS-347|1|Fall|2009|A-
12345|Shankar|Comp. Sci.|32|CS-101|1|Fall|2009|C
12345|Shankar|Comp. Sci.|32|CS-190|2|Spring|2009|A
12345|Shankar|Comp. Sci.|32|CS-315|1|Spring|2010|A
12345|Shankar|Comp. Sci.|32|CS-347|1|Fall|2009|A
19991|Brandt|History|80|HIS-351|1|Spring|2010|B
23121|Chavez|Finance|110|FIN-201|1|Spring|2010|C+
44553|Peltier|Physics|56|PHY-101|1|Fall|2009|B-
45678|Levy|Physics|46|CS-101|1|Fall|2009|F
45678|Levy|Physics|46|CS-101|1|Spring|2010|B+
45678|Levy|Physics|46|CS-319|1|Spring|2010|B
54321|Williams|Comp. Sci.|54|CS-101|1|Fall|2009|A-
54321|Williams|Comp. Sci.|54|CS-190|2|Spring|2009|B+
55739|Sanchez|Music|38|MU-199|1|Spring|2010|A-
70557|Snow|Physics|0|||||
76543|Brown|Comp. Sci.|58|CS-101|1|Fall|2009|A
76543|Brown|Comp. Sci.|58|CS-319|2|Spring|2010|A
76653|Aoi|Elec. Eng.|60|EE-181|1|Spring|2009|C
98765|Bourikas|Elec. Eng.|98|CS-101|1|Fall|2009|C-
98765|Bourikas|Elec. Eng.|98|CS-315|1|Spring|2010|B
98988|Tanaka|Biology|120|BIO-101|1|Summer|2009|A
98988|Tanaka|Biology|120|BIO-301|1|Summer|2010|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We mention earlier that &lt;strong&gt;on&lt;/strong&gt; and &lt;strong&gt;where&lt;/strong&gt; behave differently
for outer join. Let’s consider the following example&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This gives the following result &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sqlite&amp;gt; select * from student left outer join takes where student.ID = takes.ID;
ID|name|dept_name|tot_cred|ID|course_id|sec_id|semester|year|grade
00128|Zhang|Comp. Sci.|102|00128|CS-101|1|Fall|2009|A
00128|Zhang|Comp. Sci.|102|00128|CS-347|1|Fall|2009|A-
12345|Shankar|Comp. Sci.|32|12345|CS-101|1|Fall|2009|C
12345|Shankar|Comp. Sci.|32|12345|CS-190|2|Spring|2009|A
12345|Shankar|Comp. Sci.|32|12345|CS-315|1|Spring|2010|A
12345|Shankar|Comp. Sci.|32|12345|CS-347|1|Fall|2009|A
19991|Brandt|History|80|19991|HIS-351|1|Spring|2010|B
23121|Chavez|Finance|110|23121|FIN-201|1|Spring|2010|C+
44553|Peltier|Physics|56|44553|PHY-101|1|Fall|2009|B-
45678|Levy|Physics|46|45678|CS-101|1|Fall|2009|F
45678|Levy|Physics|46|45678|CS-101|1|Spring|2010|B+
45678|Levy|Physics|46|45678|CS-319|1|Spring|2010|B
54321|Williams|Comp. Sci.|54|54321|CS-101|1|Fall|2009|A-
54321|Williams|Comp. Sci.|54|54321|CS-190|2|Spring|2009|B+
55739|Sanchez|Music|38|55739|MU-199|1|Spring|2010|A-
76543|Brown|Comp. Sci.|58|76543|CS-101|1|Fall|2009|A
76543|Brown|Comp. Sci.|58|76543|CS-319|2|Spring|2010|A
76653|Aoi|Elec. Eng.|60|76653|EE-181|1|Spring|2009|C
98765|Bourikas|Elec. Eng.|98|98765|CS-101|1|Fall|2009|C-
98765|Bourikas|Elec. Eng.|98|98765|CS-315|1|Spring|2010|B
98988|Tanaka|Biology|120|98988|BIO-101|1|Summer|2009|A
98988|Tanaka|Biology|120|98988|BIO-301|1|Summer|2010|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, &lt;code&gt;left outer join&lt;/code&gt; esentially returns a cartesian product of two relations.
Since there is no tuple in &lt;code&gt;take&lt;/code&gt; with &lt;code&gt;ID = 70577&lt;/code&gt;, every time a tuple appears in the outer
join with name = &lt;code&gt;"Snow"&lt;/code&gt;, the values for &lt;code&gt;student.ID&lt;/code&gt; and &lt;code&gt;takes.ID&lt;/code&gt; must be different, and
such tuples would be eliminated by the &lt;code&gt;where&lt;/code&gt; clause predicate. Thus, student
Snow never appears in the result of the latter query.&lt;/p&gt;
&lt;h3 id="relational-algebra-perspective"&gt;Relational algebra perspective&lt;/h3&gt;
&lt;p&gt;In the previous section, we spend quite some time understanding &lt;code&gt;join&lt;/code&gt; from SQL
perspective. In this section, we try to under the clause from relational algebra
perspective.&lt;/p&gt;
&lt;p&gt;In relational algebra, a operator accepts (one or two) relation instances as argument
and returns a relation instance as the result: &lt;span class="math"&gt;\(f(R_1, R_2) \to R_3\)&lt;/span&gt;. We have 
the following operators:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(\sigma\)&lt;/span&gt;: select rows from a relation  (i.e. &lt;span class="math"&gt;\(\sigma_{\text{grade} &amp;lt; B}(takes)\)&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(\pi\)&lt;/span&gt;: extract columns from a relation (i.e. &lt;span class="math"&gt;\(\pi_{\text{ID, name}}(student)\)&lt;/span&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, for join we have following definitions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;condition joins: &lt;span class="math"&gt;\(R \bowtie_c S = \sigma_c (R \times S)\)&lt;/span&gt; 
(i.e. &lt;span class="math"&gt;\(\text{student} \bowtie_{\text{student.id &amp;lt; takes.id}} \text{takes}\)&lt;/span&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Does this look familar to you? Yes, this exactly corresponds to &lt;code&gt;join ... on ...&lt;/code&gt; usage.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;equijoin: &lt;span class="math"&gt;\(R \bowtie_c S\)&lt;/span&gt; ( &lt;span class="math"&gt;\(c\)&lt;/span&gt; consists &lt;strong&gt;solely&lt;/strong&gt; of equalities)
(i.e. &lt;span class="math"&gt;\(\text{student} \bowtie_{\text{student.id = takes.id}} \text{takes}\)&lt;/span&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is equivalent to &lt;code&gt;join ... using (...)&lt;/code&gt; usage.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;natural join: &lt;span class="math"&gt;\(R \bowtie S\)&lt;/span&gt; (equijoin where equalities are specified on all fields having the same 
name in &lt;span class="math"&gt;\(R\)&lt;/span&gt; and &lt;span class="math"&gt;\(S\)&lt;/span&gt;) (i.e. &lt;span class="math"&gt;\(\text{student} \bowtie \text{takes}\)&lt;/span&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Well, this is exactly the &lt;code&gt;natural join&lt;/code&gt; usage.&lt;/p&gt;
&lt;p&gt;In fact, this perspective is acutally how people explain &lt;code&gt;join&lt;/code&gt; to others. There
are two excellent pages offer graphical explaination to this concept. Their links
are attached in the “Links to resources” section.&lt;/p&gt;
&lt;h2 id="examples"&gt;Examples&lt;/h2&gt;
&lt;h3 id="leetcode-175"&gt;Leetcode 175&lt;/h3&gt;
&lt;p&gt;Now, let’s take a look at &lt;a href="https://leetcode.com/problems/combine-two-tables/#/description"&gt;leetcode 175. Combine Two tables&lt;/a&gt;
for practice. &lt;/p&gt;
&lt;p&gt;The problem asks us to &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Write a SQL query for a report that provides the following information
(FirstName, LastName, City, State) 
for each person in the Person table, regardless if there is an address for each of those people.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“regardless if there is an address for each of those people” is a clear indicator
for us to use &lt;code&gt;outer join&lt;/code&gt; because we still want to keep all the person even 
they may not appear in the “Address” table. There are several queries we can write&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersonId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersonId&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PersonId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersonId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersonId&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Solution&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;natural&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;outer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We should have no trouble to understand these queries now. &lt;/p&gt;
&lt;h3 id="example-two"&gt;Example Two&lt;/h3&gt;
&lt;p&gt;Suppose we have two tables &lt;code&gt;t1&lt;/code&gt; and &lt;code&gt;t2&lt;/code&gt; that are created like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;create table t1 (a int, b char(1));
create table t2 (b char(1), c char(10));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also, &lt;code&gt;t1.b&lt;/code&gt; contains 7 &lt;code&gt;'x'&lt;/code&gt; and &lt;code&gt;t2.b&lt;/code&gt; contains 3 &lt;code&gt;'x'&lt;/code&gt;. If we do &lt;code&gt;select * from t1 inner join t2 on t1.b = t2.b&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;what are the columns of the resulting queries?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The result contains 4 columns: &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;. Note that one difference between &lt;code&gt;join ... on&lt;/code&gt; and 
&lt;code&gt;natural join&lt;/code&gt; or &lt;code&gt;join ... using&lt;/code&gt; is that &lt;code&gt;join ... on&lt;/code&gt; will keep the columns with same attributes from
two tables (e.g. &lt;code&gt;b&lt;/code&gt; in this case) while the other two will only keep one column only.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How many rows does the result set contain?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Remember &lt;code&gt;join&lt;/code&gt; is a special case of cartesian product: only keep the rows that have the same value on the
shared attributes between two tables. In this example, since there are 7 &lt;code&gt;'x'&lt;/code&gt; in &lt;code&gt;t1&lt;/code&gt; and 3 &lt;code&gt;'x'&lt;/code&gt; in &lt;code&gt;t2&lt;/code&gt;,
we will have 21 rows in the end.&lt;/p&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Database-System-Concepts-Computer-Science/dp/0073523321"&gt;Database System Concepts&lt;/a&gt;
Chapter 3, 4&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ibm.com/developerworks/data/tutorials/db2-cert6104/index.html"&gt;DB2 10.1 fundamentals certification exam 610 prep, Part 4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pages.cs.wisc.edu/~dbbook/"&gt;Database Management Systems&lt;/a&gt; Chapter 4&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins"&gt;Code project page&lt;/a&gt; and
&lt;a href="https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join"&gt;SO post&lt;/a&gt; have
nice graphic explanation to this concept.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.w3resource.com/sqlite/sqlite-natural-join.php"&gt;What is natural join in SQLite?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Tables appeard in this post are from the &lt;a href="http://db-book.com/"&gt;supplementary resources&lt;/a&gt; of the 
&lt;a href="https://www.amazon.com/Database-System-Concepts-Computer-Science/dp/0073523321"&gt;Database System Concepts&lt;/a&gt; book. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;code&gt;on true&lt;/code&gt; is equivalent to &lt;code&gt;student left outer join takes&lt;/code&gt;. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Database"></category><category term="database"></category><category term="sql"></category><category term="relational-algebra"></category><category term="leetcode"></category></entry><entry><title>The tortoise and the hare</title><link href="https://zhu45.org/posts/2017/Jun/18/the-tortoise-and-the-hare/" rel="alternate"></link><published>2017-06-18T20:20:00+08:00</published><updated>2017-06-18T20:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-06-18:/posts/2017/Jun/18/the-tortoise-and-the-hare/</id><summary type="html">&lt;p&gt;Floyd&amp;rsquo;s Tortoise and Hare w/ leetcode 142, 287&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently, I start to work on &lt;a href="https://github.com/xxks-kkk/shuati"&gt;leetcode’s problems&lt;/a&gt;. 
My goal is to solve two problems per day (mission possible, right?). The problems I’m looking
at are &lt;a href="https://leetcode.com/problems/linked-list-cycle-ii/"&gt;142. Linked List Cycle II&lt;/a&gt; and 
&lt;a href="https://leetcode.com/problems/find-the-duplicate-number/"&gt;287. Find the Duplicate Number&lt;/a&gt;, 
which both can be solved by Folyd’s Tortoise and Hare algorithm.&lt;/p&gt;
&lt;p&gt;This post will try to take a deeper look at the correctness of the algorithm and
how to apply it to solve problems.&lt;/p&gt;
&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd.27s_Tortoise_and_Hare"&gt;Floyd’s Tortoise and Hare algorithm&lt;/a&gt;
is used with three purposes under the context of linked list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Detect whether there is a cycle in the list&lt;/li&gt;
&lt;li&gt;Find the starting point of the cycle (i.e. list 1-&amp;gt;4-&amp;gt;3-&amp;gt;4, starting point is 4)&lt;/li&gt;
&lt;li&gt;Decide the length of the cycle (i.e. 2 for above example)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The algorithm idea is following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We use two pointers: tortoise and hare. Both start at the beginning of the list.
Hare runs twice as fas the tortoise.&lt;/li&gt;
&lt;li&gt;If there is no-cycle, then hare will reach the finish line before the tortoise.&lt;/li&gt;
&lt;li&gt;If there is a cycle, then hare will always be ahead and eventually he would
so far ahead that he laps the tortoise. That’s the place we know we have a cycle in the list.&lt;/li&gt;
&lt;li&gt;Once we detect the cycle, we send hare back to the beginning and advance both of 
them at the same speed until they meet again. The second meeting place, which we’ll prove
immediately, is the entry point of the cycle. &lt;/li&gt;
&lt;li&gt;Then, one of them will keep moving to finish the victory lap to find the period
of the cycle.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key difference when the list has a cycle is that at some point on the track, 
the hare will be at the same spot as the tortoise …&lt;/p&gt;
&lt;h2 id="proof-of-correctness"&gt;Proof of correctness&lt;/h2&gt;
&lt;p&gt;Let &lt;span class="math"&gt;\(\mu\)&lt;/span&gt; be the index of the start of the cycle, and let &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; be period of the
cycle. Let &lt;span class="math"&gt;\(i\)&lt;/span&gt; be the distance (i.e number of nodes) that tortoise travels and
let &lt;span class="math"&gt;\(x_i\)&lt;/span&gt; denotes the index of the node at which both tortoise and hare meet. &lt;span class="math"&gt;\(x_0\)&lt;/span&gt;
is the first node in the list.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The notation here is similar to the concept in physics: distance vs. displacement.
&lt;span class="math"&gt;\(i\)&lt;/span&gt; is the “distance” or the number of nodes that our character (tortoise or hare)
has travelled since the beginning of the list and 
&lt;span class="math"&gt;\(x_i\)&lt;/span&gt; is the “displacement” between the first node and the current node that our
characters are at.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The key observation for showing the correctness of the algorithm lies in 
the following fact:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
x_{j+k\lambda} = x_j \text{ for all integers }j \ge \mu \text{ and } k \ge 0 \label{eqn:1}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;This statement says that going around the loop any number of times takes you 
back to the same places as long as you start somewhere on the loop. Let’s 
define the following set of notation here for future use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(y\)&lt;/span&gt; be the displacement between &lt;span class="math"&gt;\(x_{\mu}\)&lt;/span&gt; and &lt;span class="math"&gt;\(x_i\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(m\)&lt;/span&gt; be the number of laps that tortoise have travelled before he meets
with hare at &lt;span class="math"&gt;\(x_i\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(n\)&lt;/span&gt; be the number of laps that hare have travelled before he meets with 
tortoise at &lt;span class="math"&gt;\(x_i\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since the hare runs twice as fast as the tortoise, then the distance hare travelled
when he meets with tortoise is &lt;span class="math"&gt;\(2i\)&lt;/span&gt; &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. Then, we have the following set of equations&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray}
i = \mu + y + m \cdot \lambda  \label{eqn:2} \\
2i = \mu + y + n \cdot \lambda \label{eqn:3}
\end{eqnarray}
$$&lt;/div&gt;
&lt;p&gt;Now we subtract \ref{eqn:2} from \ref{eqn:3} and we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
i = (n-m) \cdot \lambda \label {eqn:4}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;Let’s revisit our key observation \ref{eqn:1} and set &lt;span class="math"&gt;\(j = \mu\)&lt;/span&gt; and &lt;span class="math"&gt;\(k = (n-m)\)&lt;/span&gt;, we have
&lt;span class="math"&gt;\(x_{\mu + (n-m)\lambda} = x_{\mu}\)&lt;/span&gt;. Then, by \ref{eqn:4}, we have
&lt;span class="math"&gt;\(x_{\mu + i} = x_{\mu}\)&lt;/span&gt;, which can be rewritten as &lt;span class="math"&gt;\(x_{i+\mu} = x_{\mu}\)&lt;/span&gt;!!! This equation
tells us that the node at which the cycle begins (i.e &lt;span class="math"&gt;\(x_{\mu}\)&lt;/span&gt;) is exactly the
same node as the node that is &lt;span class="math"&gt;\(\mu\)&lt;/span&gt; nodes away from the index at which tortoise and hare meet
(i.e. &lt;span class="math"&gt;\(x_i\)&lt;/span&gt;).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The proof can be much shorter once we have &lt;span class="math"&gt;\(x_{2i} = x_i\)&lt;/span&gt;. By \ref{eqn:1}, we
also have &lt;span class="math"&gt;\(x_{i+k\lambda} = x_{2i}\)&lt;/span&gt;, which leads to &lt;span class="math"&gt;\(k\lambda = i\)&lt;/span&gt;. Since
&lt;span class="math"&gt;\(x_\mu\)&lt;/span&gt; also meets the condition of \ref{eqn:1}, we have &lt;span class="math"&gt;\(x_{\mu + k\lambda} = x_\mu\)&lt;/span&gt;.
Substitutes &lt;span class="math"&gt;\(i = k\lambda\)&lt;/span&gt; in and get &lt;span class="math"&gt;\(x_{\mu+i} = x_\mu\)&lt;/span&gt;. The conclusion follows.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="two-problems"&gt;Two problems&lt;/h2&gt;
&lt;h3 id="142-linked-list-cycle-ii"&gt;142. Linked List Cycle II&lt;/h3&gt;
&lt;p&gt;The first problem is a straightforward application of the algorithm: 
Given a linked list, return the node where the cycle begins. If there is no cycle, return &lt;code&gt;NULL&lt;/code&gt;.
The code is following&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Definition for singly-linked list.&lt;/span&gt;
&lt;span class="cm"&gt; * struct ListNode {&lt;/span&gt;
&lt;span class="cm"&gt; *     int val;&lt;/span&gt;
&lt;span class="cm"&gt; *     struct ListNode *next;&lt;/span&gt;
&lt;span class="cm"&gt; * };&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;detectCycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// there is a cycle&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// find the entry location&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// there is no cycle&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="287-find-the-duplicate-number"&gt;287. Find the Duplicate Number&lt;/h3&gt;
&lt;p&gt;This problem is a lot tricker than a previous one: we need identify this problem
can also be solved by the Floyd’s Tortoise and Hare algorithm, which is not obvious
at first glance&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given an array nums containing &lt;span class="math"&gt;\(n + 1\)&lt;/span&gt; integers where each integer is 
between &lt;span class="math"&gt;\(1\)&lt;/span&gt; and &lt;span class="math"&gt;\(n\)&lt;/span&gt; (inclusive), prove that at least one duplicate number 
must exist. Assume that there is only one duplicate number, find the duplicate one.
note: There is only one duplicate number in the array, but it could be repeated more than once.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The key point is to identify that the problem description is another way of 
describing a linked list, which requires somewhat deeper understanding of the
algorithm itself.&lt;/p&gt;
&lt;p&gt;The algorithm is, in fact, used to find a cycle in a sequence of 
&lt;a href="https://en.wikipedia.org/wiki/Iterated_function"&gt;iterated function&lt;/a&gt; values:&lt;/p&gt;
&lt;div class="math"&gt;$$
x_0, x1 = f(x_0), x_2 = f(x_1), \dots, x_i = f(x_{i-1}), \dots
$$&lt;/div&gt;
&lt;p&gt;For example, the sequence &lt;span class="math"&gt;\(1,3,4,2,1\)&lt;/span&gt; can be considered as a sequence of 
iterated function values with &lt;span class="math"&gt;\(x_0 = 1, x_1 = f(1) = 3, x_2 = f(3) = 4,
x_3 = f(4) = 2, x_4 = f(2) = 1\)&lt;/span&gt;. Let’s try another representation:&lt;/p&gt;
&lt;table class="table  table-striped table-hover"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;index&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;value&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Surprisingly, the function &lt;span class="math"&gt;\(f\)&lt;/span&gt; simply map the index to the corresponding values.
With this table, the above sequence can be converted as a linked list:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="o"&gt;--------------&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This list is constructed by the definition of a sequence of iterated function values.
The arrow (&lt;code&gt;-&amp;gt;&lt;/code&gt;) is the function &lt;span class="math"&gt;\(f\)&lt;/span&gt;. Then, we can apply our algorithm to solve 
this problem:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;findDuplicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numsSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tortoise&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hare&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This implementation slightly deviates from the algorithm description above:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Tortoise and hare don’t start from the same place at the beginning. This doesn’t
matter really because eventually they will be in the loop.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We use &lt;code&gt;tortoise = nums[tortoise]&lt;/code&gt; instead of &lt;code&gt;tortoise++&lt;/code&gt; for advancing tortoise,
for example. This is the place where “a sequence of iterative function values” idea
appears. In fact, this is also how we constructed our linked list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;hare = 0&lt;/code&gt; not &lt;code&gt;hare = nums[0]&lt;/code&gt; can be confusing. We can think about this from our linked
list representation: our list starts from &lt;span class="math"&gt;\(0\)&lt;/span&gt; (required by &lt;span class="math"&gt;\(f\)&lt;/span&gt;, which maps index to value)
and if we starts from &lt;code&gt;hare = nums[0]&lt;/code&gt;, that violates our algorithm.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;span class="math"&gt;\(x_{2i} = x_i\)&lt;/span&gt; immediately follows this statement. Then, if we let&lt;br/&gt;
&lt;span class="math"&gt;\(l\)&lt;/span&gt; be the number of laps by which hare is ahead, then &lt;span class="math"&gt;\(2i = i + l \cdot \lambda\)&lt;/span&gt;
and we have &lt;span class="math"&gt;\(i = l\lambda\)&lt;/span&gt;. Then we set &lt;span class="math"&gt;\(k=l\)&lt;/span&gt; in \ref{eqn:1} and reach the same
conclusion. This way we don’t need to define &lt;span class="math"&gt;\(y\)&lt;/span&gt;,&lt;span class="math"&gt;\(m\)&lt;/span&gt;,&lt;span class="math"&gt;\(n\)&lt;/span&gt;, which can make proof
a little simpler notation-wise. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="linked-list"></category><category term="leetcode"></category><category term="algorithm"></category></entry><entry><title>Python case study: leetcode scraper</title><link href="https://zhu45.org/posts/2017/Jun/15/python-case-study-leetcode-scraper/" rel="alternate"></link><published>2017-06-15T21:22:00+08:00</published><updated>2017-06-15T21:22:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-06-15:/posts/2017/Jun/15/python-case-study-leetcode-scraper/</id><summary type="html">&lt;p&gt;a record of python usage appears in the leetcode scraper&lt;/p&gt;</summary><content type="html">&lt;p&gt;It has been many years since 
&lt;a href="http://pages.cs.wisc.edu/~zeyuan/projects/notes/diveintopython/diveintopython.html"&gt;last time&lt;/a&gt; 
I touched python. Things get very rusty. Recently, I have been practicing
my algorithm skills on leetcode and I keep all my solutions in a 
&lt;a href="https://github.com/xxks-kkk/shuati"&gt;github repo&lt;/a&gt;. I want my source files 
have consistency formatting shown below&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt; * [Source]&lt;/span&gt;
&lt;span class="cm"&gt; * &lt;/span&gt;
&lt;span class="cm"&gt; * https://leetcode.com/problems/same-tree/&lt;/span&gt;
&lt;span class="cm"&gt; *&lt;/span&gt;
&lt;span class="cm"&gt; * [Problem Description]&lt;/span&gt;
&lt;span class="cm"&gt; *&lt;/span&gt;
&lt;span class="cm"&gt; * Given two binary trees, write a function to check if they are equal or not.&lt;/span&gt;
&lt;span class="cm"&gt; * &lt;/span&gt;
&lt;span class="cm"&gt; * Two binary trees are considered equal if they are structurally identical &lt;/span&gt;
&lt;span class="cm"&gt; * and the nodes have the same value. &lt;/span&gt;
&lt;span class="cm"&gt; *&lt;/span&gt;
&lt;span class="cm"&gt; * [Companies]&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Source code begins here ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The overhead of adding this header comment can be quite large. 
So, I ask myself if there is a better way
to make the whole process automated as much as possible. Python and its famous
&lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/"&gt;beautifulsoup&lt;/a&gt; library &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt; 
immediately come into my mind.&lt;/p&gt;
&lt;p&gt;In this post, I’ll highlight some python usage appeared in the script, which costs
me quite some time on googling. Please leave your comment if you find any non-pythonic 
usage. The code script is available 
&lt;a href="https://github.com/xxks-kkk/shuati/blob/master/scraper.py"&gt;here&lt;/a&gt;. I’ll use
&lt;a href="https://leetcode.com/problems/reverse-linked-list-ii/#/description"&gt;92. ReverseLinkedList II&lt;/a&gt;
leetcode page as a working example to demonstrate the python techniques.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env python3.6&lt;/span&gt;
&lt;span class="c1"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The very first thing is “shebang”. This is important for our task because
the web page is often written in the unicode (i.e. mathematical symbols).
This shebang will help us avoid unicode &amp;amp; ascii madness. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;bs4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We use a lot of libraries through &lt;code&gt;import&lt;/code&gt;. If I use &lt;em&gt;import module&lt;/em&gt;, I have to use quantifier
for any module function call (i.e. &lt;code&gt;sys.exit()&lt;/code&gt;). By the contrast, I can directly
call the module function if I do &lt;em&gt;from module import&lt;/em&gt;. This brings a question on
when to use which. Here, I want to quote the explanation from 
&lt;a href="http://www.diveintopython.net/object_oriented_framework/importing_modules.html"&gt;Dive Into Python&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When should you use &lt;em&gt;from module import&lt;/em&gt;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you will be accessing attributes and methods often and don’t want to type the module name over and over, use “&lt;em&gt;from module import&lt;/em&gt;”.&lt;/li&gt;
&lt;li&gt;If you want to selectively import some attributes and methods but not others, use “&lt;em&gt;from module import&lt;/em&gt;”.&lt;/li&gt;
&lt;li&gt;If the module contains attributes or functions with the same name as ones in your module, you must use “&lt;em&gt;import module&lt;/em&gt;” to avoid name conflicts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The author makes extra remark: Use &lt;em&gt;from module import *&lt;/em&gt; sparingly, because it makes it difficult to determine where a particular function or attribute came from, and that makes debugging and refactoring more difficult.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'url is &lt;/span&gt;&lt;span class="si"&gt;{:s}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I used to really like Python2.7 and not a big fan of Python3. However, with python2.7 EOS,
change must be made. the &lt;code&gt;print&lt;/code&gt; statement is how we do format printing in python3.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"lxml"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, I use &lt;a href="http://docs.python-requests.org/en/master/user/quickstart/#make-a-request"&gt;requests&lt;/a&gt;
library to fetch the content of the &lt;code&gt;url&lt;/code&gt; and then feed it into our &lt;code&gt;BeautifulSoup&lt;/code&gt;
with parser &lt;code&gt;lxml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next step is to actual scrap the data from leetcode page. The first thing I 
do is to get the question title. Leetcode page has the following structure 
for the question title&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"question-title clearfix"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-4 col-md-5 col-sm-6 col-sm-push-6 col-md-push-7 col-lg-push-8"&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"widgets"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"like-and-dislike"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"question-like"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"add-to-list"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"add-to-favorite"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"col-lg-8 col-md-7 col-sm-6 col-sm-pull-6 col-md-pull-5 col-lg-pull-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            92. Reverse Linked List II
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the question title (“92. Reverse Linked List II”) is wrapped around
by the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag with class name &lt;code&gt;question-title&lt;/code&gt;. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;title_corp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"div"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;class_&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"question-title"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;title_raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title_corp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, we invoke &lt;a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc/#calling-a-tag-is-like-calling-find-all"&gt;find_all&lt;/a&gt;
method from beautiful soup to find all the &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; tags with class name &lt;code&gt;question-title&lt;/code&gt;.
Fortunately, &lt;code&gt;question-title&lt;/code&gt; class appears only once in the whole html page. 
That allows us to directly access its using &lt;code&gt;title_corp[0]&lt;/code&gt;. In addition, as you can see
from html source code above, &lt;code&gt;&amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;&lt;/code&gt; appears only once and it wraps our
problem title. So, we can directly access the content of &lt;code&gt;&amp;lt;h3&amp;gt;&amp;lt;/h3&amp;gt;&lt;/code&gt; tags by 
&lt;code&gt;title_corp[0].h3.get_text()&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;code&gt;find_all&lt;/code&gt; returns a “ResultSet” object in beautifulSoup. This object contains
a set of tags that match with &lt;code&gt;find_all&lt;/code&gt; function argument criteria. In our case,
our criteria is &lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt; tag with class name &lt;code&gt;question-title&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now, once we have the title string, we want to process it into our desired form.
Our scraper script will go into the 
&lt;a href="https://github.com/xxks-kkk/shuati/tree/master/leetcode"&gt;leetcode directory of the shuati repo&lt;/a&gt;
and create the question directory with the format 
“[question number]-[question title in mixed case with the first letter of each internal word capitalized]”
For example, “92. Reverse Linked List II” will lead to a directory 
&lt;code&gt;./leetcode/92-ReverseLinkedListII&lt;/code&gt;. The source file name is similar to the 
directory name: &lt;code&gt;reverseLinkedListII.c&lt;/code&gt;. That’s what following code chunk tries to achieve&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class="n"&gt;title_lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title_raw&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;title_lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;methodcaller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'strip'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;title_lines&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;title_rdy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title_lines&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title_rdy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./leetcode/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;title_lines = title_raw.split('\n')&lt;/code&gt; will split the whole text into a list 
of strings with each string being a line of code. In our case, this will give
&lt;code&gt;['', '            92. Reverse Linked List II', '          ']&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As you can see our result contains empty string, string with multiple leading
whitespaces, and string with only whitespaces. We need to do some cleanup to keep
only the question title. The first thing we do is to take out the empty string and
the string with only whitespaces. This is done by 
&lt;code&gt;title_lines = list(filter(operator.methodcaller('strip'), title_lines))&lt;/code&gt; &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;.
&lt;a href="https://docs.python.org/2/library/functions.html#filter"&gt;filter&lt;/a&gt; 
creates a list of elements for which a function (the 1st argument of &lt;code&gt;filter&lt;/code&gt;) 
returns true. &lt;code&gt;operator.methodcaller('strip')&lt;/code&gt; uses 
&lt;a href="https://docs.python.org/3/library/operator.html#operator.methodcaller"&gt;methodcaller&lt;/a&gt;,
which applies &lt;code&gt;strip&lt;/code&gt; function to each element of &lt;code&gt;title_lines&lt;/code&gt;. The function will
return true only when our string has some characters in it. This will lead to
&lt;code&gt;['            92. Reverse Linked List II']&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Here is an example of &lt;code&gt;methodcaller&lt;/code&gt;: After
&lt;code&gt;f = methodcaller('name', 'foo', bar=1)&lt;/code&gt;, the call &lt;code&gt;f(b)&lt;/code&gt; returns &lt;code&gt;b.name('foo', bar=1)&lt;/code&gt;.
In our case, &lt;code&gt;filter&lt;/code&gt; will apply &lt;code&gt;operator.methodcaller('strip')&lt;/code&gt; on &lt;code&gt;title_lines&lt;/code&gt;, which
is basically &lt;code&gt;title_lines.strip()&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now, we will work on our title string. 
&lt;code&gt;title_rdy = title_lines[0].lstrip(' ').replace(".", "-").split(' ')&lt;/code&gt; removes
leading whitespace (&lt;code&gt;lstrip(' ')&lt;/code&gt;) and replace &lt;code&gt;.&lt;/code&gt; with &lt;code&gt;-&lt;/code&gt;, and then &lt;code&gt;split&lt;/code&gt;
our string into words: &lt;code&gt;['92-', 'Reverse', 'Linked', 'List', 'II']&lt;/code&gt;. We are ready
to form our directory by &lt;code&gt;join&lt;/code&gt; the words together (&lt;code&gt;title = "".join(title_rdy)&lt;/code&gt;)
and get &lt;code&gt;92-ReverseLinkedListII&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Our file name should look like &lt;code&gt;reverseLinkedListII.c&lt;/code&gt;. This invloves a use of 
regular expression to get rid of &lt;code&gt;92-&lt;/code&gt; and convert the first character of the rest 
of string into lower case. The code is below&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;".c"&lt;/span&gt;
&lt;span class="n"&gt;pat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;"^(\d+)-"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;():]&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"w"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The regular expression is best illsutrated from a snippet taken from 
&lt;a href="https://docs.python.org/3/library/re.html"&gt;re&lt;/a&gt; library&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tony@tiremove_thisger.net"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"remove_this"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;():]&lt;/span&gt;
&lt;span class="s1"&gt;'tony@tiger.net'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;^&lt;/code&gt; matches the beginning of the string and &lt;code&gt;\d&lt;/code&gt; means numeric digits and &lt;code&gt;+&lt;/code&gt;
means at least once appearance (of &lt;code&gt;\d&lt;/code&gt;). Just like official doc snippet above,
&lt;code&gt;filename=title[:m.start()] + title[m.end():]&lt;/code&gt; removes, for instance, &lt;code&gt;92-&lt;/code&gt; and
leaves us &lt;code&gt;ReverseLinkedListII&lt;/code&gt; &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;. One thing to notice right now is that our
&lt;code&gt;filename&lt;/code&gt; has object type &lt;code&gt;str&lt;/code&gt;, which is immutable. This means that we cannot
edit the variable itself. &lt;code&gt;filename=filename[0].lower() + filename[1:]&lt;/code&gt; is 
a typical way to handle immutable &lt;code&gt;str&lt;/code&gt; object, which, in our case, lower the 
first character case and append it back to the rest of string.&lt;/p&gt;
&lt;p&gt;The last point needs to notice is &lt;code&gt;line = line.replace("\r", "").replace("\n", "")&lt;/code&gt;,
which removes carriage return character (&lt;code&gt;^M&lt;/code&gt;) and linux newline character.&lt;/p&gt;
&lt;p&gt;That’s it for the leetcode scraper. This is actually the first scraper I have
ever written. It is not as hard as I imagined. I think that’s majorly because of
the powerful python language and its libraries.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Here is &lt;a href="http://web.stanford.edu/~zlotnick/TextAsData/Web_Scraping_with_Beautiful_Soup.html"&gt;a good tutorial&lt;/a&gt; on beautifulSoup. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;This line is found from 
&lt;a href="https://stackoverflow.com/questions/8449454/remove-strings-containing-only-white-spaces-from-list"&gt;this SO post&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;I do a &lt;a href="http://pages.cs.wisc.edu/~zeyuan/projects/notes/diveintopython/chap7.html"&gt;quick summary&lt;/a&gt; of
regular expression in python. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="programming languages"></category><category term="python"></category><category term="scraping"></category><category term="beautifulsoup"></category><category term="regex"></category></entry><entry><title>Solving recurrence relations (part 2)</title><link href="https://zhu45.org/posts/2017/Jun/12/solving-recurrence-relations-part-2/" rel="alternate"></link><published>2017-06-12T17:20:00+08:00</published><updated>2017-06-12T17:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-06-12:/posts/2017/Jun/12/solving-recurrence-relations-part-2/</id><summary type="html">&lt;p&gt;Additional ways to solve recurrence relation&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://zhu45.org/posts/2017/Feb/02/solving-recurrence-relations-in-a-nutshell/"&gt;Several months ago&lt;/a&gt;, 
I breifly summarize the ways to solve recurrence relations. At the end of that post,
I indicate that different types of recurrence relation may require different kinds 
of treatments to solve them. Thus, this post will be the first “Downloadable Content (DLC)”
with the aim to solve the recurrence relation: &lt;span class="math"&gt;\(T(N) = 2T(N/2) + N\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;This recurrence relation comes from merge sort and the algorithm itself represents
a classic divide-and-conquer strategy: in order to sort &lt;span class="math"&gt;\(N\)&lt;/span&gt; elements, we can
sort &lt;span class="math"&gt;\(N/2\)&lt;/span&gt; elements first 
(i.e., &lt;em&gt;divide&lt;/em&gt; the problem into smaller problems and solve recursively),
and then we merge two sorted &lt;span class="math"&gt;\(N/2\)&lt;/span&gt; elements back into one &lt;span class="math"&gt;\(N\)&lt;/span&gt; sorted array
(i.e., we patch toghter the answer in &lt;em&gt;conquer&lt;/em&gt; phase.)&lt;/p&gt;
&lt;p&gt;The exactly recurrence relation we try to solve is the following with assumption
that &lt;span class="math"&gt;\(N\)&lt;/span&gt; is a power of 2:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*} 
T(1) &amp;amp;=&amp;amp; 1 \\
T(N) &amp;amp;=&amp;amp; 2T(N/2) + N 
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;There are two ways to solve this recurrence relation:&lt;/p&gt;
&lt;h2 id="method-1-construct-a-telescoping-sum"&gt;Method 1: Construct a telescoping sum&lt;/h2&gt;
&lt;p&gt;The goal of this method is to construct a telescoping sum (i.e see
&lt;a href="https://en.wikipedia.org/wiki/Telescoping_series"&gt;telescope series&lt;/a&gt; to get a sense
of &lt;em&gt;telescoping&lt;/em&gt;) with the aim
to find a relation between &lt;span class="math"&gt;\(T(N)\)&lt;/span&gt; and &lt;span class="math"&gt;\(T(1)\)&lt;/span&gt; (or the base cases, in general). &lt;/p&gt;
&lt;p&gt;Let’s work through our example above to demonstrate this method. We divide the
recurrence relation through by &lt;span class="math"&gt;\(N\)&lt;/span&gt; and repeatively doing so for every possible &lt;span class="math"&gt;\(N\)&lt;/span&gt;
(i.e. &lt;span class="math"&gt;\(N, N/2, N/4, \dots, 2, 1\)&lt;/span&gt;) and see what we can get:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*} 
\frac{T(N)}{N} &amp;amp;=&amp;amp; \frac{T(N/2)}{N/2} + 1 \\
\frac{T(N/2)}{N/2} &amp;amp;=&amp;amp; \frac{T(N/4)}{N/4} + 1 \\
\frac{T(N/4)}{N/4} &amp;amp;=&amp;amp; \frac{T(N/8)}{N/8} + 1 \\
\vdots \\
\frac{T(2)}{2} &amp;amp;=&amp;amp; \frac{T(1)}{1} + 1 \\
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;We add up all the equations: we add all of the terms on the left-hand side and set
the result equal to the sum of all of the terms on the right-hand side. This leads
to a &lt;em&gt;telescoping&lt;/em&gt; sum: all the terms that appear on both sides get cancelled. 
For example, the term &lt;span class="math"&gt;\(T(N/2)/(N/2)\)&lt;/span&gt; appears on both sides and thus cancels.
After everything is added, the final result is:&lt;/p&gt;
&lt;div class="math"&gt;$$
\frac{T(N)}{N} = \frac{T(1)}{1} + \log N \cdot 1
$$&lt;/div&gt;
&lt;p&gt;because all of the other terms cancel and there are &lt;span class="math"&gt;\(\log N\)&lt;/span&gt; equations, and so all
the &lt;span class="math"&gt;\(1\)&lt;/span&gt;s at the end of these equations add up to &lt;span class="math"&gt;\(\log N\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;for this recurrence relation, it is necessary to divide through &lt;span class="math"&gt;\(N\)&lt;/span&gt; in order
to get telescoping sum. However, how to construct telescoping sum is case by case.
For instance, for a recurrence relation &lt;span class="math"&gt;\(NT(N) = (N+1)T(N-1) + 2cN\)&lt;/span&gt;, we need to 
divide &lt;span class="math"&gt;\(N(N+1)\)&lt;/span&gt;. For a recurrence relation &lt;span class="math"&gt;\(T(N) = T(N-1) + cN\)&lt;/span&gt; &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;, we don’t need to 
do any division. We just need to use the recurrence relation repeatively for different
&lt;span class="math"&gt;\(N\)&lt;/span&gt; to construct the telescoping sum (i.e. &lt;span class="math"&gt;\(T(N-1) = T(N-2) + c(N-1)\)&lt;/span&gt;, 
&lt;span class="math"&gt;\(T(N-2) = T(N-3) + c(N-2)\)&lt;/span&gt;, and so on.)&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="method-2-iteratively-substitute"&gt;Method 2: Iteratively substitute&lt;/h2&gt;
&lt;p&gt;For this method, we continuely substitute the recurrence relation on the right-hand
side with the hope to find a pattern of the general solution to the recurrence relation.&lt;/p&gt;
&lt;p&gt;We have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*} 
T(N) &amp;amp;=&amp;amp; 2T(N/2) + N \\
T(N/2) &amp;amp;=&amp;amp; 2T(N/4) + N/2 
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Then, we substitute the second equation back into the first equation’s right-hand side and 
we get:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray}
T(N) &amp;amp;=&amp;amp; 2(2T(N/4)+N/2) + N \nonumber \\
     &amp;amp;=&amp;amp; 4T(N/4) + 2N \label{eqn:1}
\end{eqnarray}
$$&lt;/div&gt;
&lt;p&gt;Now, we can substitute &lt;span class="math"&gt;\(N/4\)&lt;/span&gt; into the main equation, we see that&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray}
T(N) &amp;amp;=&amp;amp; 4(2T(N/8)+N/4) + 2N \nonumber \\
     &amp;amp;=&amp;amp; 8T(N/8) + 3N \label{eqn:2}
\end{eqnarray}
$$&lt;/div&gt;
&lt;p&gt;We can continuing this substitution, and if we observe the \ref{eqn:1} and \ref{eqn:2}
we can obtain the following pattern:&lt;/p&gt;
&lt;div class="math"&gt;$$
T(N) = 2^kT(N/2^k) + k \cdot N
$$&lt;/div&gt;
&lt;p&gt;using &lt;span class="math"&gt;\(k = \log N\)&lt;/span&gt;, we obtain&lt;/p&gt;
&lt;div class="math"&gt;$$
T(N) = NT(1) + N \log N = N\log N + N
$$&lt;/div&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;This recurrence relation is acutally a linear nonhomogeneous recurrence 
relation with constant coefficients. However, it cannot be solved by the method
I write up in the last post. I have no clue why. This recurrence relation is taken 
from MAW p243. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Mathematics"></category><category term="recursion"></category><category term="math"></category></entry><entry><title>Draw a Neural Network through Graphviz</title><link href="https://zhu45.org/posts/2017/May/25/draw-a-neural-network-through-graphviz/" rel="alternate"></link><published>2017-05-25T22:20:00+08:00</published><updated>2017-05-25T22:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-05-25:/posts/2017/May/25/draw-a-neural-network-through-graphviz/</id><summary type="html">&lt;p&gt;Use NN as an example to show graphviz tricks&lt;/p&gt;</summary><content type="html">&lt;h2 id="preface"&gt;Preface&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://graphviz.org/"&gt;Graphviz&lt;/a&gt; is a language (called DOT) and
a set of tools to automatically generate graphs. It is widely used
by researchers to do visualizations in papers. Essentially, you just
need to provide a textual descritption of the graph regarding its topological
structure (i.e. what nodes are, how they are connected, etc) and Graphviz will
figure out the layout of the image by itself. Usually, the generated layout works
out well but quite often, like this &lt;a href="https://hbfs.wordpress.com/2014/09/30/a-quick-primer-on-graphviz/"&gt;post&lt;/a&gt;
mentioned, can be a “finicky beast”. So, I decide to share some tips I learned about
Graphviz.&lt;/p&gt;
&lt;p&gt;Specifically, in this post, I’ll demonstrate how we can draw the Neural Network shown in the 
&lt;a href="https://zhu45.org/posts/2017/May/23/andrew-ngs-ml-week-04-05/"&gt;last post&lt;/a&gt; and use this as an example
to show some tricks in Graphviz to tweak the layout &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;. Let’s get started!&lt;/p&gt;
&lt;h2 id="draw-a-neural-network"&gt;Draw a neural network&lt;/h2&gt;
&lt;p&gt;If you do a quick search regarding “graphviz neural network example”, you’ll highly
likely see the below picture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Multiclass neural network example" class="img-responsive" src="https://zhu45.org/images/multiclass_neural_network_example.png"/&gt;&lt;/p&gt;
&lt;p&gt;This is probably the simplest Graphviz demonstration on Neural Network. The
code for this picture can be obtained &lt;a href="https://gist.github.com/thigm85/5760134"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, when I’m preparing my last post, I’m not quite satisified with the example above.
I want to clearly label all the nodes in all layers and make distinction among feature
input, bias term, hidden units, and output units. So, I decide to draw one on my own.&lt;/p&gt;
&lt;p&gt;Here is the &lt;a href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/graphviz-drawings/nn3.dot"&gt;code&lt;/a&gt;
that generates the picture below &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;. Let me briefly
highlights some key points in the code:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Custom neural network diagram" class="img-responsive" src="https://zhu45.org/images/nn2.png"/&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;rankdir = LR;
splines=false;
edge[style=invis];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;rankdir=LR&lt;/code&gt; makes the directed graphs drawn from left to right.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;splines=false&lt;/code&gt; controls how the edges are represented and in this case, edges 
are drawn as line segments.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;edge[style=invis]&lt;/code&gt; forces edges to become invisible. This is a common trick to tweak
graphviz layout. &lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{
&lt;span class="w"&gt;  &lt;/span&gt;node&lt;span class="w"&gt; &lt;/span&gt;[shape=circle,&lt;span class="w"&gt; &lt;/span&gt;color=yellow,&lt;span class="w"&gt; &lt;/span&gt;style=filled,&lt;span class="w"&gt; &lt;/span&gt;fillcolor=yellow];
&lt;span class="w"&gt;  &lt;/span&gt;x0&lt;span class="w"&gt; &lt;/span&gt;[label=&lt;span class="nt"&gt;&amp;lt;x&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;sub&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&lt;/span&gt;&amp;gt;];&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;a02&lt;span class="w"&gt; &lt;/span&gt;[label=&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;sub&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;&lt;/span&gt;(2)&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt;&amp;gt;];&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;a03&lt;span class="w"&gt; &lt;/span&gt;[label=&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;sub&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&amp;lt;sup&amp;gt;&lt;/span&gt;(3)&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt;&amp;gt;];
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;node[...]&lt;/code&gt; sets the default node property: specify the node shape, node color. This
node property will apply to three nodes: &lt;code&gt;x0&lt;/code&gt;, &lt;code&gt;a02&lt;/code&gt;, &lt;code&gt;a03&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x0 [label=&amp;lt;x&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt;&amp;gt;]&lt;/code&gt; specify the text label for node &lt;code&gt;x0&lt;/code&gt;. The text for label
is specified in &lt;a href="http://www.graphviz.org/doc/info/shapes.html#html"&gt;HTML-like&lt;/a&gt; and this is 
how we write subscript and superscript in Graphviz.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{...}&lt;/code&gt; specifies the scope of the node property. This code chunk as a whole shows
how we can specify several nodes at the once with the same node property &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;x3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;rank=same&lt;/code&gt; is another trick I’ll talk about later. This specifies what “layer”
(or “rank” by official term) a set of nodes belongs. You can read &lt;a href="http://www.graphviz.org/doc/info/attrs.html#d:rank"&gt;the official doc&lt;/a&gt; for the details.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x0-&amp;gt;...-&amp;gt;x3&lt;/code&gt; specifies the relative position of the four nodes. Since the graph is
arranged from left to right (indicate by &lt;code&gt;rankdir = LR&lt;/code&gt;), then the “layer” is vertical.
Then by &lt;code&gt;x0-&amp;gt;...-&amp;gt;x3&lt;/code&gt;, the first node will be &lt;code&gt;x0&lt;/code&gt;, followed by &lt;code&gt;x1&lt;/code&gt;, and so on. Also,
we have &lt;code&gt;edge[style=invis]&lt;/code&gt; and this will hide the edges among these four nodes. This 
is how we draw the NN layers.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;a02&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;a03&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;This line is used to prevent tilting of the graph. As you can see, we specify
how the nodes should be arranged in a layer but we don’t much constraint on how
the layers should be positioned except &lt;code&gt;rankdir=LR&lt;/code&gt;, which says layers should be 
ordered from left to right. &lt;code&gt;a02-&amp;gt;a03&lt;/code&gt; says layer with &lt;code&gt;a02&lt;/code&gt; should be lined up with 
layer with &lt;code&gt;a03&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;l0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"layer 1 (input layer)"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;l0&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;l0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;This code chunk is how we add label text to each layer. As you can see we use
another node &lt;code&gt;l0&lt;/code&gt; with shape &lt;code&gt;plaintext&lt;/code&gt;, which says &lt;code&gt;l0&lt;/code&gt; is just a text message.
Then we connect it with the first node of layer 1 &lt;code&gt;x0&lt;/code&gt;, which serves as attaching
the text to the layer 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;edge[style=solid, tailport=e, headport=w];
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;We specify the edge style again. This will only affect the edges after this setup
not before. One small trick here is &lt;code&gt;tailport=e, headport=w&lt;/code&gt;. This will let all the edges
point to the same position.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a22&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a52&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a02&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a22&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a52&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a33&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a43&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a53&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a03&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a13&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a33&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a43&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;a53&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;O1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;O2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;O3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;O4&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;This code chunk is how we actually draw the edges. In the simple example above,
it explicitly draws the edges between two nodes. It is quite pain to do. Above code
chunk provides a simpler way to achieve the same purpose.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="graphviz-tricks"&gt;Graphviz tricks&lt;/h2&gt;
&lt;p&gt;From our NN drawing example, there are two recurring tricks when we tweak Graphviz 
picture layout:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Invisible nodes/edges&lt;/li&gt;
&lt;li&gt;Rank constraints&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="invisible-nodesedges"&gt;Invisible nodes/edges&lt;/h3&gt;
&lt;p&gt;In the above example, we use invisible edges to specify the ordering of nodes within
each NN layer. In addition, we use node with &lt;code&gt;plaintext&lt;/code&gt; shape to specify the text label
in the layer.&lt;/p&gt;
&lt;p&gt;Usually, we use invisible edges to specify what nodes should line up and sometimes
we use invisible nodes to take up space to keep the graph in a specific structure.
&lt;a href="https://stackoverflow.com/questions/7374108/graphviz-node-placement-and-rankdir"&gt;This SO post&lt;/a&gt;
demonstrates how we can use invisible nodes and edges in combination to create 
a fancy picture. 
&lt;a href="https://stackoverflow.com/questions/27091591/graphviz-dot-vertical-alignment-of-nodes"&gt;This SO post&lt;/a&gt;
is another example to show how to use “invisible edges” (it uses another trick called
&lt;code&gt;group&lt;/code&gt; attribute).&lt;/p&gt;
&lt;h3 id="rank-constraints"&gt;Rank constraints&lt;/h3&gt;
&lt;p&gt;If you check &lt;a href="http://www.graphviz.org/doc/info/attrs.html#d:rank"&gt;official doc&lt;/a&gt;,
here is what rank does:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rank constraints on the nodes in a subgraph. If rank=”same”, 
all nodes are placed on the same rank. If rank=”min”, all nodes are placed on the minimum rank. 
If rank=”source”, all nodes are placed on the minimum rank, and the only nodes on the minimum 
rank belong to some subgraph whose rank attribute is “source” or “min”. Analogous criteria hold 
for rank=”max” and rank=”sink”. (Note: the minimum rank is topmost or leftmost, and the maximum 
rank is bottommost or rightmost.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s demonstrate this description with a simple example &lt;sup id="fnref:4"&gt;&lt;a class="footnote-ref" href="#fn:4"&gt;4&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;digraph&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This example gives a graph with two rows. &lt;code&gt;a-&amp;gt;b&lt;/code&gt; is above &lt;code&gt;c-&amp;gt;d&lt;/code&gt;.
However, if I change &lt;code&gt;{rank=source; a-&amp;gt;b;}&lt;/code&gt; to &lt;code&gt;{rank=min; a-&amp;gt;b;}&lt;/code&gt;, we’ll
end up with one row: &lt;code&gt;a-&amp;gt;b&lt;/code&gt; will be to the left of &lt;code&gt;c-&amp;gt;d&lt;/code&gt;. This is due to
the difference between &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;source&lt;/code&gt;: &lt;code&gt;min&lt;/code&gt; allows other subgraphs in the
minimum rank. However, &lt;code&gt;source&lt;/code&gt; only allows other subgraphs of &lt;code&gt;min&lt;/code&gt; or &lt;code&gt;source&lt;/code&gt;
to be on the minimum rank (we have &lt;code&gt;same&lt;/code&gt; in this case).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sink&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; works similarly. For instance, the below example gives a picture
with &lt;code&gt;c-&amp;gt;d&lt;/code&gt; at the top and &lt;code&gt;a-&amp;gt;b&lt;/code&gt; at the bottom:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;digraph&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;same&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Of course, Graphviz is not the only tool that can produce beautiful pictures. 
&lt;a href="http://www.texample.net/"&gt;TikZ&lt;/a&gt; is another popular tool. You can check out 
&lt;a href="http://www.texample.net/tikz/examples/neural-network/"&gt;its NN example&lt;/a&gt; for comparison. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Technically, the code used to generate the blog NN picture is 
&lt;a href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/graphviz-drawings/nn2.dot"&gt;this one&lt;/a&gt;
but the code I explained above is much more concise. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Check out 
&lt;a href="https://stackoverflow.com/questions/28853898/groups-of-nodes-with-the-same-attributes-in-graphviz-file"&gt;this SO post&lt;/a&gt;
for more examples on grouping nodes with the same attributes. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;The example is adapted from &lt;a href="https://stackoverflow.com/questions/6149834/rank-attribute-is-confusing-to-me"&gt;this SO post&lt;/a&gt;. &lt;a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="tools"></category><category term="machine learning"></category><category term="graphviz"></category><category term="neural network"></category></entry><entry><title>Andrew Ng's ML Week 04 - 05</title><link href="https://zhu45.org/posts/2017/May/23/andrew-ngs-ml-week-04-05/" rel="alternate"></link><published>2017-05-23T22:20:00+08:00</published><updated>2017-05-23T22:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-05-23:/posts/2017/May/23/andrew-ngs-ml-week-04-05/</id><summary type="html">&lt;p&gt;Neural network&lt;/p&gt;</summary><content type="html">&lt;p&gt;Week 4 and 5 mainly talks about one important learning technique called “Neural Networks”.
It is especially heplful when there are many features and hence, many combinations
for the &lt;a href="https://zhu45.org/posts/2017/May/05/andrew-ngs-ml-week-01-03/"&gt;linear or logistic regressions&lt;/a&gt;. 
Interestingly, I studied neural networks
&lt;a href="https://www.dropbox.com/s/hkym4s135amgmxv/HU.pdf?dl=0"&gt;previously&lt;/a&gt; 
when I was a student at college. It may feel different when we revisit old friend.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#model"&gt;Model&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#representations"&gt;Representations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#train-a-neural-network"&gt;Train a neural network&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#1-pick-a-network-architecture"&gt;1. Pick a network architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-randomly-initialize-weights"&gt;2. Randomly initialize weights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-forward-propagation"&gt;3. Forward propagation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-cost-function-jtheta"&gt;4. Cost function \(J(\theta)\)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-backpropagation"&gt;5. Backpropagation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#implementation-details"&gt;Implementation details&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="model"&gt;Model&lt;/h2&gt;
&lt;h3 id="representations"&gt;Representations&lt;/h3&gt;
&lt;p&gt;Below picture shows a typical neural network (I’ll use NN as a shorthand). &lt;/p&gt;
&lt;p&gt;&lt;img alt="Neural network diagram" class="img-responsive" src="https://zhu45.org/images/nn2.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(L =\)&lt;/span&gt; total number of layers in network (i.e. &lt;span class="math"&gt;\(L = 4\)&lt;/span&gt; for the above NN)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(S_l =\)&lt;/span&gt; number of units (not counting bias unit) in layer &lt;span class="math"&gt;\(l\)&lt;/span&gt; 
(i.e., &lt;span class="math"&gt;\(S_1 = 3\)&lt;/span&gt;, &lt;span class="math"&gt;\(S_2 = S_3 = 5\)&lt;/span&gt;, &lt;span class="math"&gt;\(S_4 = S_L = 4\)&lt;/span&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(a_i^l =\)&lt;/span&gt; “activation” of unit &lt;span class="math"&gt;\(i\)&lt;/span&gt; in layer &lt;span class="math"&gt;\(l\)&lt;/span&gt;. In fact, input features
&lt;span class="math"&gt;\(x_0, x_1, x_2, x_3\)&lt;/span&gt; can also be represented as &lt;span class="math"&gt;\(a_0^{(1)}, a_1^{(1)}, a_1^{(2)}, a_1^{(3)}\)&lt;/span&gt;
respectively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\Theta^{(l)} =\)&lt;/span&gt; matrix of weights controlling function mapping from layer &lt;span class="math"&gt;\(l\)&lt;/span&gt; to layer &lt;span class="math"&gt;\(l+1\)&lt;/span&gt;.
For example,&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="math"&gt;$$
\Theta^{(1)} = \begin{bmatrix} 
\theta_{10}^{(1)} &amp;amp;&amp;amp; \theta_{11}^{(1)} &amp;amp;&amp;amp; \theta_{12}^{(1)} &amp;amp;&amp;amp; \theta_{13}^{(1)} \\
\theta_{20}^{(1)} &amp;amp;&amp;amp; \theta_{21}^{(1)} &amp;amp;&amp;amp; \theta_{22}^{(1)} &amp;amp;&amp;amp; \theta_{23}^{(1)} \\
\dots \\
\theta_{50}^{(1)} &amp;amp;&amp;amp; \theta_{51}^{(1)} &amp;amp;&amp;amp; \theta_{52}^{(1)} &amp;amp;&amp;amp; \theta_{53}^{(1)} \\
\end{bmatrix}
$$&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Notation here may look confusing. One example to help understand is
&lt;span class="math"&gt;\(\theta_{10}^{1}\)&lt;/span&gt; means weight from &lt;span class="math"&gt;\(x_0\)&lt;/span&gt; in layer &lt;span class="math"&gt;\(1\)&lt;/span&gt; to &lt;span class="math"&gt;\(a_1\)&lt;/span&gt; in layer &lt;span class="math"&gt;\(2\)&lt;/span&gt;. In other words,
&lt;span class="math"&gt;\(\theta_{ji}^{l}\)&lt;/span&gt; means weight from &lt;span class="math"&gt;\(a_i^{l}\)&lt;/span&gt; to &lt;span class="math"&gt;\(a_j^{l+1}\)&lt;/span&gt;. Then the rows in the
matrix can be thought of as the weights from neurons in layer &lt;span class="math"&gt;\(l\)&lt;/span&gt; to corresponding &lt;span class="math"&gt;\(a_j\)&lt;/span&gt; in layer &lt;span class="math"&gt;\(l+1\)&lt;/span&gt; 
(i.e., 1st row in the above example means weights from layer &lt;span class="math"&gt;\(1\)&lt;/span&gt; to &lt;span class="math"&gt;\(a_1\)&lt;/span&gt; in layer &lt;span class="math"&gt;\(2\)&lt;/span&gt;). 
Explicitly, the number of columns in our current theta matrix is equal to the number of 
nodes in our current layer (including the bias unit). The number of rows is equal to the number
of nodes in the next layer (excluding the bias unit).&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(K =\)&lt;/span&gt; number of neurons in the output layer (i.e. &lt;span class="math"&gt;\(S_L = K\)&lt;/span&gt;). In other words, &lt;span class="math"&gt;\(K\)&lt;/span&gt; represents the number of classes
in multi-class classification. This indicates that &lt;span class="math"&gt;\(h_\theta(x) = \mathbb{R}^K\)&lt;/span&gt;. &lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Usually, in our training sets {&lt;span class="math"&gt;\((x^{(1)}, y^{(1)}), \dots, (x^{(m)}, y^{(m)})\)&lt;/span&gt;}, we are given actual label (i.e. 
&lt;span class="math"&gt;\(y^{(9)} = 10\)&lt;/span&gt; for handwritten digit recognition). However, we need to transform those labels into &lt;span class="math"&gt;\(\mathbb{R}^k\)&lt;/span&gt; by doing,for 
instance, create &lt;span class="math"&gt;\(\mathbb{R}^{10}\)&lt;/span&gt; vector with last position being &lt;span class="math"&gt;\(1\)&lt;/span&gt; and rest being &lt;span class="math"&gt;\(0\)&lt;/span&gt;
as the representation for &lt;span class="math"&gt;\(y^{(9)} = 10\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;With the above notations, we have the following property:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If NN has &lt;span class="math"&gt;\(S_l\)&lt;/span&gt; units in layer &lt;span class="math"&gt;\(l\)&lt;/span&gt;, &lt;span class="math"&gt;\(S_{l+1}\)&lt;/span&gt; units in layer &lt;span class="math"&gt;\(l+1\)&lt;/span&gt;, then &lt;span class="math"&gt;\(\Theta^{(l)}\)&lt;/span&gt; will be dimension 
&lt;span class="math"&gt;\(S_{l+1} \times (S_l + 1)\)&lt;/span&gt;. &lt;span class="math"&gt;\(+1\)&lt;/span&gt; comes from the bias unit (shown in yellow in above NN picture). &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="train-a-neural-network"&gt;Train a neural network&lt;/h3&gt;
&lt;h4 id="1-pick-a-network-architecture"&gt;1. Pick a network architecture&lt;/h4&gt;
&lt;p&gt;The first step is to pick a network architecture. Specifically, the connectivity patterns between neurons. Prof. Ng 
says a reasonable default is to either have &lt;span class="math"&gt;\(1\)&lt;/span&gt; hidden layer, or if &lt;span class="math"&gt;\(&amp;gt;1\)&lt;/span&gt; hidden layer, have the same number of 
hidden units in every layer. Usually, the more hidden units the better. &lt;/p&gt;
&lt;h4 id="2-randomly-initialize-weights"&gt;2. Randomly initialize weights&lt;/h4&gt;
&lt;p&gt;Zero initialization is considered bad for NN (i.e. &lt;span class="math"&gt;\(\theta_{ij}^{l} = 0\)&lt;/span&gt; for all &lt;span class="math"&gt;\(i,j,l\)&lt;/span&gt;) because our activation output and
gradient will all be identical and essentially we comput one feature in this network. That’s why we need to randomly 
initialize the weights for symmetry breaking. &lt;/p&gt;
&lt;p&gt;One effective strategy is to randomly select values for &lt;span class="math"&gt;\(\theta_{ij}^{l}\)&lt;/span&gt; uniformly in the range 
[&lt;span class="math"&gt;\(-\epsilon_\text{init}\)&lt;/span&gt;,&lt;span class="math"&gt;\(\epsilon_\text{init}\)&lt;/span&gt;]. We can choose &lt;span class="math"&gt;\(\epsilon_\text{init}\)&lt;/span&gt; based upon
the number of units in the network. A good choice of &lt;span class="math"&gt;\(\epsilon_\text{init}\)&lt;/span&gt; is 
&lt;span class="math"&gt;\(\epsilon_\text{init} = \frac{\sqrt{6}}{\sqrt{L_\text{in} + L_\text{out}}}\)&lt;/span&gt;, where
&lt;span class="math"&gt;\(L_\text{in} = S_l\)&lt;/span&gt; and &lt;span class="math"&gt;\(L_\text{out} = S_{l+1}\)&lt;/span&gt;, which are the the number of units
in the layers adjacent to &lt;span class="math"&gt;\(\Theta^{(l)}\)&lt;/span&gt;. Take above NN as an example, our 
&lt;span class="math"&gt;\(\epsilon_\text{init}\)&lt;/span&gt; will be &lt;span class="math"&gt;\(0.87\)&lt;/span&gt;, which is calculated from &lt;span class="math"&gt;\(\frac{\sqrt{6}}{\sqrt{3+5}}\)&lt;/span&gt;. &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h4 id="3-forward-propagation"&gt;3. Forward propagation&lt;/h4&gt;
&lt;p&gt;The next step we need to do is to use forward propagation to get &lt;span class="math"&gt;\(h_\theta(x^{(i)})\)&lt;/span&gt; for any &lt;span class="math"&gt;\(x^{(i)}\)&lt;/span&gt;.
Let’s use above NN as an example to demonstrate how forward propagation is done. There are
&lt;span class="math"&gt;\(4\)&lt;/span&gt; output units in the output layer and thus, our &lt;span class="math"&gt;\(h_\theta(x^{(i)})\)&lt;/span&gt; looks like&lt;/p&gt;
&lt;div class="math"&gt;$$
h_\theta(x^{(i)}) = \begin{bmatrix}
a_1^{(4)} \\
a_2^{(4)} \\
a_3^{(4)} \\
a_4^{(4)} \\
\end{bmatrix}
$$&lt;/div&gt;
&lt;p&gt;The general idea for the forward propagation is that we take in the input from previous 
layer, and multiply with our weights, and then apply our sigmoid function to get the
activation value for the current layer. We start with the input layer and do this 
iteratively until we get to output layer, which its activation value will be our 
&lt;span class="math"&gt;\(h_\theta(x^{(i)})\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Concretely, let’s first represent our input layer (with bias term) as  &lt;span class="math"&gt;\(x\)&lt;/span&gt; and 
define a new variable &lt;span class="math"&gt;\(z^{(j)}\)&lt;/span&gt; as following:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{align*}
&amp;amp; x = \begin{bmatrix} x_0 \\ x_1 \\ \dots \\ x_n \end{bmatrix}
&amp;amp;&amp;amp;
z^{(j)} = \begin{bmatrix} z_1^{(j)} \\ z_2^{(j)} \\ \dots \\ z_n^{(j)} \end{bmatrix}
\end{align*}
$$&lt;/div&gt;
&lt;p&gt;Then, we can calculate the activation value &lt;span class="math"&gt;\(a^{(j)}\)&lt;/span&gt; for the layer j as follows
(treating &lt;span class="math"&gt;\(x = a^{(1)}\)&lt;/span&gt;):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add bias term &lt;span class="math"&gt;\(a_0^{(j-1)} = 1\)&lt;/span&gt; to &lt;span class="math"&gt;\(a^{(j-1)}\)&lt;/span&gt; and our new &lt;span class="math"&gt;\(a^{(j-1)}\)&lt;/span&gt; looks like &lt;/p&gt;
&lt;p&gt;
&lt;div class="math"&gt;$$
a^{(j-1)} = \begin{bmatrix} a_0^{(j-1)} \\ a_1^{(j-1)} \\ \dots \\ a_n^{(j-1)} \end{bmatrix}
$$&lt;/div&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Calculate &lt;span class="math"&gt;\(z^{(j)}\)&lt;/span&gt; as follows:&lt;/p&gt;
&lt;p&gt;
&lt;div class="math"&gt;$$
z^{(j)} = \Theta^{(j-1)}a^{(j-1)}
$$&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Here, &lt;span class="math"&gt;\(\Theta^{(j-1)}\)&lt;/span&gt; has dimension &lt;span class="math"&gt;\(S_j \times (S_{j-1} + 1)\)&lt;/span&gt; and &lt;span class="math"&gt;\(a^{(j-1)}\)&lt;/span&gt; has 
dimension &lt;span class="math"&gt;\((S_{j-1} + 1) \times 1\)&lt;/span&gt;. Then, our vector &lt;span class="math"&gt;\(z^{(j)}\)&lt;/span&gt; has height &lt;span class="math"&gt;\(S_j\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We get a vector of our activation nodes for layer &lt;span class="math"&gt;\(j\)&lt;/span&gt; as follows:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="math"&gt;$$
a^{(j)} = g(z^{(j)})
$$&lt;/div&gt;
&lt;p&gt;We repeat these three steps and get &lt;span class="math"&gt;\(h_\theta(x^{(i)})\)&lt;/span&gt;, which in our NN is the activation
value &lt;span class="math"&gt;\(a^{(4)}\)&lt;/span&gt; for &lt;span class="math"&gt;\(i\)&lt;/span&gt;-th training example. &lt;/p&gt;
&lt;p&gt;One key intuition for forward propagation is that the whole process is just like logistic
regression except that rather than using original feature &lt;span class="math"&gt;\(x_1, x_2, \dots, x_n\)&lt;/span&gt;, it uses
new features &lt;span class="math"&gt;\(a^{(L-1)}\)&lt;/span&gt;, which are learned by the NN itself.&lt;/p&gt;
&lt;h4 id="4-cost-function-jtheta"&gt;4. Cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;Now we need to compute the cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; of the NN in order to minimize
the classification error with the given data. Since NN shares a lot similarity with
the logistic regression, it’s no hard to imagine that the NN’s cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt;
shares the similar form with the logistic regression’s cost function:&lt;/p&gt;
&lt;div class="math"&gt;$$
J(\theta) = - \frac{1}{m} [ \sum_{i=1}^m \sum_{k=1}^K y_k^{(i)} \log h_\theta(x^{(i)})_k + 
(1 - y_k^{(i)}) \log(1-h_\theta(x^{(i)})_k)] + \frac{\lambda}{2m} 
\sum_{l=1}^{L-1}\sum_{i=1}^{S_l}\sum_{j=1}^{S_l+1}(\theta_{ji}^{(l)})^2
$$&lt;/div&gt;
&lt;p&gt;Here, &lt;span class="math"&gt;\(h_\theta(x^{(i)})_k\)&lt;/span&gt; means the &lt;span class="math"&gt;\(k\)&lt;/span&gt;th output in the output layer. The second part of 
the equation summs over all the weights &lt;span class="math"&gt;\(\theta_{ji}^{(l)}\)&lt;/span&gt; except the bias term (i.e. &lt;span class="math"&gt;\(i=0\)&lt;/span&gt;).&lt;/p&gt;
&lt;h4 id="5-backpropagation"&gt;5. Backpropagation&lt;/h4&gt;
&lt;p&gt;Once we have the cost function, our next step is to find the derivative terms 
&lt;span class="math"&gt;\(\frac{\partial J(\theta)}{\partial \theta_{ij}^{(l)}}\)&lt;/span&gt; for every &lt;span class="math"&gt;\(i,k,l\)&lt;/span&gt; in order to use various octave 
built-in method (i.e. &lt;code&gt;fminunc&lt;/code&gt;) to minimize &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; as a function of &lt;span class="math"&gt;\(\theta\)&lt;/span&gt;. We use backpropagation to do this.&lt;/p&gt;
&lt;p&gt;The intuition for the backpropagation is the following: given a training example &lt;span class="math"&gt;\((x^{(i)}, y^{(i)})\)&lt;/span&gt;, we will
first run forward propagation to compute all the activiations throughout the network, including the output units.
Then, for each node &lt;span class="math"&gt;\(j\)&lt;/span&gt; in layer &lt;span class="math"&gt;\(l\)&lt;/span&gt;, we would like to compute an “error term” &lt;span class="math"&gt;\(\delta_j^{(l)}\)&lt;/span&gt; that measures how
much that node was “responsible” for any errors in our output. For an output node, we can directly measure the
difference between the network’s activation and the true target value, and use that to define &lt;span class="math"&gt;\(\delta_j^{(L)}\)&lt;/span&gt;.
For the hidden units, we can compute &lt;span class="math"&gt;\(\delta_j^{l}\)&lt;/span&gt; based on a weighted average of the error terms of the nodes in layer
&lt;span class="math"&gt;\((l+1)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Here is the algorithm in details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given training set {&lt;span class="math"&gt;\((x^{(1)}, y^{(1)}), \dots, (x^{(m)}, y^{(m)})\)&lt;/span&gt;}&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set &lt;span class="math"&gt;\(\Delta_{ij}^{(l)} = 0\)&lt;/span&gt; (for all &lt;span class="math"&gt;\(i,l,j\)&lt;/span&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;For i=1:m,&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;perform &lt;a href="#3-forward-propagation"&gt;forward propagation&lt;/a&gt; to compute &lt;span class="math"&gt;\(a^{(l)}\)&lt;/span&gt; for &lt;span class="math"&gt;\(l = 2, 3, \dots, L\)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;using &lt;span class="math"&gt;\(y^{(i)}\)&lt;/span&gt;, compute &lt;span class="math"&gt;\(\delta^{(L)} = a^{(L)} - y^{(i)}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;compute &lt;span class="math"&gt;\(\delta^{(L-1)}, \delta^{(L-2)}, \dots, \delta^{(2)}\)&lt;/span&gt; using 
&lt;span class="math"&gt;\(\delta^{(l)} = ((\Theta^{(l)})^T \delta^{(l+1)}).\ast a^{(l)}.\ast (1-a^{(l)})\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(\Delta_{ij}^{(l)} := \Delta_{ij}^{(l)} + a_j^{(l)}\delta_i^{(l+1)}\)&lt;/span&gt;
   (Vectorized form is &lt;span class="math"&gt;\(\Delta^{(l)} := \Delta^{(l)} + \delta^{(l+1)}(a^{(l)})^T\)&lt;/span&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(D_{ij}^{(l)} := \frac{1}{m}\Delta_{ij}^{(m)} + \frac{\lambda}{m}\theta_{ij}^{(l)} \text{ if } j \ne 0\)&lt;/span&gt; and
&lt;span class="math"&gt;\(D_{ij}^{(l)} := \frac{1}{m}\Delta_{ij}^{(m)} \text{ if } j = 0\)&lt;/span&gt;. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\frac{\partial J(\theta)}{\partial \theta_{ij}^{(l)}} = D_{ij}^{(l)}\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Intuitvely, backpropagation algorithm is alot like forward propagation running backward. We can then use gradient
descent or advanced optimization method to try to minimize &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; as a function of parameters &lt;span class="math"&gt;\(\theta\)&lt;/span&gt; &lt;sup id="fnref:5"&gt;&lt;a class="footnote-ref" href="#fn:5"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Notice that we don’t compute &lt;span class="math"&gt;\(\delta_{(1)}\)&lt;/span&gt; because &lt;span class="math"&gt;\(\delta_{(1)}\)&lt;/span&gt; is associated with the input layer, which are
features we observed from the training examples. So, there are no “error” involved. In addition, &lt;span class="math"&gt;\(.\ast\)&lt;/span&gt; means we 
do element-wise multiplication in octave.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="implementation-details"&gt;Implementation details&lt;/h2&gt;
&lt;p&gt;Week 5’s programming assignment on NN learning is the most challenging one I have met so far in this course. Initially, 
I plan to go through lots of details in terms of implementation in this section. However, after I finish the model
section above and take a look at the assignment code again, I realize that the algorithms described above reflect
fair accurately on how the code should be written. &lt;/p&gt;
&lt;p&gt;However, there is one point I want to emphasize &lt;span class="math"&gt;\(a^{(1)}\)&lt;/span&gt; is a vector with dimension &lt;span class="math"&gt;\(n \times 1\)&lt;/span&gt;. This is important
if you want to apply the algorithms exactly. When I first coded the program, my &lt;span class="math"&gt;\(a^{(1)}\)&lt;/span&gt; is a row vector with dimension
&lt;span class="math"&gt;\(1 \times n\)&lt;/span&gt;, which causes me much trouble for the rest of implementations.&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\Delta^{(l)} := \Delta^{(l)} + \delta^{(l+1)}(a^{(l)})^T\)&lt;/span&gt; looks confusing for me as well 
for the first time. My question is how many &lt;span class="math"&gt;\(\Delta^{(l)}\)&lt;/span&gt; are there. My trick is to take 
a look at the last term of the equation. &lt;span class="math"&gt;\(\delta^{(l+1)}(a^{(l)})^T\)&lt;/span&gt; indicates that &lt;span class="math"&gt;\(\Delta^{(l)}\)&lt;/span&gt;
starts with the second last layer and there is one until input layer (including).
So, in our NN above, there are three &lt;span class="math"&gt;\(\Delta^{(l)}\)&lt;/span&gt; we should update. &lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Here, it is unclear for me which two layers we should choose to calculate 
&lt;span class="math"&gt;\(\epsilon_\text{init}\)&lt;/span&gt;. In the &lt;a href="https://github.com/xxks-kkk/Code-for-blog/tree/master/2017/andrew-ng-ml/machine-learning-ex4/ex4"&gt;programming assignment 4&lt;/a&gt;,
the value is calculated from the layer 1 (input layer) and layer 2 (1st hidden layer). &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;You can use &lt;a href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/andrew-ng-ml/machine-learning-ex4/ex4/computeNumericalGradient.m"&gt;gradient checking&lt;/a&gt; 
to verify if the backpropagation is implemented correctly. &lt;a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Machine Learning"></category><category term="machine learning"></category><category term="coursera"></category><category term="neural network"></category></entry><entry><title>Andrew Ng's ML Week 01 - 03</title><link href="https://zhu45.org/posts/2017/May/05/andrew-ngs-ml-week-01-03/" rel="alternate"></link><published>2017-05-05T16:18:00+08:00</published><updated>2017-05-05T16:18:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-05-05:/posts/2017/May/05/andrew-ngs-ml-week-01-03/</id><summary type="html">&lt;p&gt;ML overview, Linear regression, Logistic regression, Regularization&lt;/p&gt;</summary><content type="html">&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#ml-overview"&gt;ML overview&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#what-is-ml"&gt;What is ML?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#types-of-ml-problems"&gt;Types of ML problems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#notation"&gt;Notation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#linear-regression"&gt;Linear regression&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#in-theory"&gt;In theory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#in-practice"&gt;In practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#linear-regression-with-regularization"&gt;Linear regression with regularization&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#in-theory_1"&gt;In theory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#in-practice_1"&gt;In practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#logistic-regression"&gt;Logistic regression&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#in-theory_2"&gt;In theory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#in-practice_2"&gt;In practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#logistic-regression-with-regularization"&gt;Logistic regression with regularization&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#in-theory_3"&gt;In theory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#in-practice_3"&gt;In practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;In my &lt;a href="https://zhu45.org/posts/2017/Apr/21/introducing-the-andrew-ngs-ml-course-study-notes/"&gt;introducing post&lt;/a&gt;, I mention that
I decide to write summary post weekly for the course. However, in practice, I find
it is very hard to do. This is mainly because I want to keep the progress in MAW 
reading while meet the coursework deadlines. So, I decide to do the summary post
based upon the module of the material itself.&lt;/p&gt;
&lt;p&gt;In addition, like MAW reading posts, I will focus on the reflection and the post itself
may not be self-contained. However, this may happen rarely.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Coursera has really well-designed programming assignment that really helps to understand
both concepts and its actual implementation. All the code snippets listed in the below
and upcoming posts are availabe &lt;a href="https://github.com/xxks-kkk/Code-for-blog/tree/master/2017/andrew-ng-ml"&gt;in my code-for-blog repo&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="ml-overview"&gt;ML overview&lt;/h2&gt;
&lt;h3 id="what-is-ml"&gt;What is ML?&lt;/h3&gt;
&lt;p&gt;The biggest take-away for me is that ML is to solve the problems that
cannot be easily solved by the programming. As mentioned by Prof. Andrew, we
know how to program the shortest path from A to B but we may have hard time
to program a solution to do image tagging, email spam checking, and so on.
The way we solve those problems is by teaching computers to do things like us
through learning algorithms.&lt;/p&gt;
&lt;p&gt;There are a lot of examples about ML mentioned in the video:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Database mining: large datasets from growth of automation/web (i.e. web click data,
medical records, biology, engineering)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Applications can’t program by hand. (i.e. autonomous helicopter, 
handwriting recognition, most of NLP, CV)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Self-customizing programs (i.e. Amazon, Netflix product recommendations)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Understanding human learning (brain, real AI)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are two definitions for ML: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Arthur Samuel: the field of study that gives computers the ability to learn
without being explicitly programmed. (older, informal definition)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tom Mitchell: A computer program is said to learn from experience &lt;span class="math"&gt;\(E\)&lt;/span&gt; with respect
to some class of tasks &lt;span class="math"&gt;\(T\)&lt;/span&gt; and performance measure &lt;span class="math"&gt;\(P\)&lt;/span&gt;, if its performance at tasks in &lt;span class="math"&gt;\(T\)&lt;/span&gt;,
as measured by &lt;span class="math"&gt;\(P\)&lt;/span&gt;, improves with experience &lt;span class="math"&gt;\(E\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Take playing checkers as an example. &lt;span class="math"&gt;\(E = \text{the experience of playing many games of checkers}\)&lt;/span&gt;;
&lt;span class="math"&gt;\(T = \text{the task of playing checkers}\)&lt;/span&gt;; &lt;span class="math"&gt;\(P = \text{the probability that the program will win the next game}\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="types-of-ml-problems"&gt;Types of ML problems&lt;/h3&gt;
&lt;p&gt;There are two general types:  Supervised learning and Unsupervised learning.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Supervised learning: ‘right’ answer given&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Regression: predict continuous valued output&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EX1: given data about the size of houses on the real estate market, try to predict their price.&lt;/li&gt;
&lt;li&gt;EX2: given a picture of a person, we predict their age on the basis of the given picture.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Classification: predict results in a discrete output (categories)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EX1: predict whether the house sells for more or less than the asking price.&lt;/li&gt;
&lt;li&gt;EX2: given a patient with a tumor, we predict whether the tumor is malignant or benign.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Unsupervised learning: little or no idea what our resuls should look like. We can
derive structure from data where we don’t necessarily know the effect of the variables.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Clustering: take a collection of 1,000,000 different genes, and find a way to automatically group
these genes into groups that are somehow similar or related by different variables (i.e. lifespan, location, roles)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Non-clustering: the “cocktail party algorithm” allows you to find structure in a 
chaotic environment (i.e. identifying individual voices and music from a mesh of sounds at a cocktail party)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Other application fields: organize computing clusters, social network analysis, market segmentation, 
astronomical data analysis&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="notation"&gt;Notation&lt;/h2&gt;
&lt;p&gt;A few notation used throughout the course:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(n = \text{number of features}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(m = \text{number of training examples}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(x^{(i)} = \text{input (features) of }i\text{th training example}\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(x_j^{(i)} = \text{value of feature }j \text{ in }i\text{th training example}\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="linear-regression"&gt;Linear regression&lt;/h2&gt;
&lt;h3 id="in-theory"&gt;In theory&lt;/h3&gt;
&lt;p&gt;For linear regression, our hypothesis is &lt;/p&gt;
&lt;div class="math"&gt;$$
h_\theta(x) = \theta_0 x_0 + \theta_1 x_1 + \dots + \theta_n x_n = \theta^T x  
$$&lt;/div&gt;
&lt;p&gt;where &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{align}
&amp;amp; x = \begin{bmatrix} x_0 \\ x_1 \\ \vdots \\ x_n \end{bmatrix} \in \mathbb{R} ^{n+1}  \label{eq:1} &amp;amp;
&amp;amp; \theta = \begin{bmatrix} \theta_0 \\ \theta_1 \\ \vdots \\ \theta_n \end{bmatrix} \in \mathbb{R} ^{n+1}
\end{align}
$$&lt;/div&gt;
&lt;p&gt;and our cost function is &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray}
J(\theta) &amp;amp;=&amp;amp; \frac{1}{2m} \sum_{i=1}^m(\theta^T x^{(i)}-y(i))^2 \label{eq:2} \\
          &amp;amp;=&amp;amp; \frac{1}{m}  \sum_{i=1}^m \underbrace{\frac{1}{2}(\theta^T x^{(i)}-y(i))^2}_{\text{cost}(h_\theta(x),y)} \label{eq:7}
\end{eqnarray}
$$&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(2\)&lt;/span&gt; in the above equation is a convenience for the computation of the gradient
descent as the derivative term of the square function will cancel out the 
&lt;span class="math"&gt;\(\frac{1}{2}\)&lt;/span&gt; term.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In order to find &lt;span class="math"&gt;\(\theta\)&lt;/span&gt; that minimizes our cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt;. Two methods are available for us:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gradient Descent&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="math"&gt;$$
\begin{align} 
\text{Repeat\{ } &amp;amp;&amp;amp;  \nonumber\\
&amp;amp;&amp;amp; \theta_j := \theta_j - \alpha \times \frac{1}{m} \sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} &amp;amp;&amp;amp;
\text{(simultaneously update $\theta_j$ for $j = 0, 1, \dots, n$)}  \label{eq:3}\\
\text{\}} \nonumber
\end{align}
$$&lt;/div&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; is called learning rate, which determines “the step we take downhill” and the part afterwards decides
which direction we want to go (derived by taking partial derivatives against &lt;span class="math"&gt;\(\theta_j\)&lt;/span&gt;)&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;&lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; should decrease after every iteration of batch gradient descent. If it is not, we
want to try smaller &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt;. However, if &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; is too small, gradient descent can be slow to converge
(i.e. &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; decreases by less than &lt;span class="math"&gt;\(\epsilon\)&lt;/span&gt; (i.e. &lt;span class="math"&gt;\(10^{-3}\)&lt;/span&gt;) in one iteration). If &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; is too large,
&lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; may not decrease on every iteration; may not converge. Thuse, to choose &lt;span class="math"&gt;\(\alpha\)&lt;/span&gt;, we can 
try a range of values, say &lt;span class="math"&gt;\(\dots, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, \dots\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Normal Equation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We just directly calculate the partial derivatives for every &lt;span class="math"&gt;\(\theta_j\)&lt;/span&gt; and set it equals to zero 
(i.e &lt;span class="math"&gt;\(\frac{\partial}{\partial \theta_j}J(\theta) = 0\)&lt;/span&gt; for every &lt;span class="math"&gt;\(j\)&lt;/span&gt;) and we get:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
\theta = (X^TX)^{-1}X^Ty \label{eq:4}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;where &lt;span class="math"&gt;\(X\)&lt;/span&gt; is called &lt;em&gt;design matrix&lt;/em&gt;, and it has form&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{align*} 
&amp;amp; X = \left[\begin{array}{ccc} - &amp;amp; (x^{(1)})^T &amp;amp; - \\ - &amp;amp; (x^{(2)})^T &amp;amp; - \\ &amp;amp; \vdots &amp;amp; \\ - &amp;amp; (x^{(m)})^T &amp;amp; -\end{array} \right] &amp;amp;
x^{(i)} = \begin{bmatrix}x_0^{(i)} \\ \vdots \\ x_n^{(i)} \end{bmatrix} \in \mathbb{R} ^{n+1}
\end{align*}
$$&lt;/div&gt;
&lt;h3 id="in-practice"&gt;In practice&lt;/h3&gt;
&lt;p&gt;One tricky thing I find out when I work through quiz and programming problems 
is the gap between the mathematical representation and the actual implementation.&lt;/p&gt;
&lt;p&gt;For the cost function \ref{eq:2}, we implement it in Octave as following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;J = 1/(2*m) * (X*theta-y)' * (X*theta - y); 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;where &lt;/p&gt;
&lt;div class="math"&gt;$$
X = \begin{bmatrix} 
x_0^{(1)} &amp;amp;&amp;amp; x_1^{(1)} &amp;amp;&amp;amp; \dots &amp;amp;&amp;amp; x_n^{(1)} \\
x_0^{(2)} &amp;amp;&amp;amp; x_1^{(2)} &amp;amp;&amp;amp; \dots &amp;amp;&amp;amp; x_n^{(2)} \\
\vdots \\
x_0^{(m)} &amp;amp;&amp;amp; x_1^{(m)} &amp;amp;&amp;amp; \dots &amp;amp;&amp;amp; x_n^{(m)}
\end{bmatrix}
$$&lt;/div&gt;
&lt;p&gt;Note that &lt;span class="math"&gt;\(X\)&lt;/span&gt; here is different from \ref{eq:1} because &lt;span class="math"&gt;\(X\)&lt;/span&gt; here is to faciltate
the vectorized cost function calculation in program (i.e Octave) and it is natural
fit with how the data actually loaded into the program.&lt;/p&gt;
&lt;p&gt;Also, if you take a look at our octave calculation above, we explictly avoid doing
summation in \ref{eq:2}. We can put both vectorized form used in octave and mathematical
definition side by side to see the pattern:&lt;/p&gt;
&lt;div class="math"&gt;$$
J(\theta) = \frac{1}{2m}(X\theta-y)^T(X\theta-y) = \frac{1}{2m} \sum_{i=1}^m(\theta^T x^{(i)}-y(i))^2
$$&lt;/div&gt;
&lt;p&gt;Matrix transpose times matrix itself is a commonly-seen technique that is used to
avoid explictly summation.&lt;/p&gt;
&lt;p&gt;For gradient descent, we can calculate like the following in octave:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;theta = theta - alpha &lt;span class="gs"&gt;* 1/m *&lt;/span&gt; (X'*(X*theta - y));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let me use an example to illustrate why we can calculate \ref{eq:3} like above.
Suppose &lt;span class="math"&gt;\(m = 4\)&lt;/span&gt; with &lt;span class="math"&gt;\(h_\theta(x) = \theta_0x_0+\theta_1x_1\)&lt;/span&gt;.
Then, we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{align*} 
X = \begin{bmatrix}
x_0^{(1)} &amp;amp;&amp;amp; x_1^{(1)} \\
x_0^{(2)} &amp;amp;&amp;amp; x_1^{(2)} \\
x_0^{(3)} &amp;amp;&amp;amp; x_1^{(3)} \\
x_0^{(4)} &amp;amp;&amp;amp; x_1^{(4)} \\
\end{bmatrix} &amp;amp;&amp;amp;
\theta = \begin{bmatrix} \theta_0 \\ \theta_1 \end{bmatrix} &amp;amp;&amp;amp;
h_\theta(x^{(i)}) - y^{(i)} = \begin{bmatrix}
\theta_0 + \theta_1x_1^{(1)} - y^{(1)} \\
\vdots \\
\theta_0 + \theta_1x_1^{(4)} - y^{(4)}
\end{bmatrix}
\end{align*}
$$&lt;/div&gt;
&lt;p&gt;so now we can show why:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
\sum_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} \text{ for all $j$ } &amp;amp;=&amp;amp;
(\theta_0 + \theta_1x_1^{(1)} - y^{(1)}) \begin{bmatrix} x_0^{(1)} \\ x_1^{(1)} \end{bmatrix} + 
\dots + (\theta_0 + \theta_1x_1^{(4)} - y^{(4)}) \begin{bmatrix} x_0^{(4)} \\ x_1^{(4)} \end{bmatrix} \\
&amp;amp;=&amp;amp; \begin{bmatrix} x_0^{(1)} &amp;amp;&amp;amp; x_0^{(2)} &amp;amp;&amp;amp; x_0^{(3)} &amp;amp;&amp;amp; x_0^{(4)} \\
x_1^{(1)} &amp;amp;&amp;amp; x_1^{(2)} &amp;amp;&amp;amp; x_1^{(3)} &amp;amp;&amp;amp; x_1^{(4)}
\end{bmatrix} 
\begin{bmatrix}
\theta_0 + \theta_1x_1^{(1)} - y^{(1)} \\
\vdots \\
\theta_0 + \theta_1x_1^{(4)} - y^{(4)}
\end{bmatrix}
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;For normal equation, we can calculate like the following in octave:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;theta = pinv(X'*X)*X'*y;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is no different than \ref{eq:4} we mentioned above.&lt;/p&gt;
&lt;h2 id="linear-regression-with-regularization"&gt;Linear regression with regularization&lt;/h2&gt;
&lt;p&gt;Quite often, we may face &lt;em&gt;overfitting&lt;/em&gt; issue, which can be fixed by either reduce number of features or
regularization.&lt;/p&gt;
&lt;p&gt;Regularization is to keep all the features, but reduce magnitude (values) of parameters &lt;span class="math"&gt;\(\theta_j\)&lt;/span&gt;. By
doing so, we can make our hypothesis simpler and less prone to overfitting.&lt;/p&gt;
&lt;h3 id="in-theory_1"&gt;In theory&lt;/h3&gt;
&lt;p&gt;With regularization, our new cost function becomes &lt;/p&gt;
&lt;div class="math"&gt;$$
J(\theta) = \frac{1}{2m}\Big[ \sum_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)})^2 + 
\underbrace{\lambda \sum_{j=1}^n \theta_j^2\Big]}_\textrm{regularization term}
$$&lt;/div&gt;
&lt;p&gt;The regularization parameter &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; controls the tradeoff between “fit the data well” and
“keep parameters small to avoid overfitting”.  If &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; is set to an extremely large
value, then we may face “underfit” issue (i.e. all &lt;span class="math"&gt;\(\theta_j\)&lt;/span&gt; for &lt;span class="math"&gt;\(j = 1, \dots, n\)&lt;/span&gt; close to 0)&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Since our cost function has changed, both gradient descent and normal equation have to adjust accordingly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gradient Descent&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="math"&gt;$$
\begin{align} 
\text{Repeat\{ } &amp;amp;&amp;amp; \nonumber \\
\theta_0 := \theta_0 - \alpha \times \frac{1}{m} \sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)} &amp;amp;&amp;amp;  \label{eq:5} \\
\theta_j := \theta_j - \alpha \times \lbrack \frac{1}{m} \sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} + 
\frac{\lambda}{m}\theta_j\rbrack &amp;amp;&amp;amp; (j = 1,2,3, \dots, n) \label{eq:6} \\
\text{\}} \nonumber
\end{align}
$$&lt;/div&gt;
&lt;p&gt;Here, it might be a good time to write out the gradient explicitly (rather than embedding them in 
the gradient descent algorithm). 
&lt;a href="http://eli.thegreenplace.net/2016/understanding-gradient-descent/"&gt;Gradient descent&lt;/a&gt; 
is only one of many algorithms that optimizes a given function. We will use other algorithms
later in the course and the only thing they require is the gradients.&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{align*}
\frac{\partial J(\theta)}{\partial \theta_0} &amp;amp;=&amp;amp; \frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} &amp;amp;&amp;amp; \text{ for } j = 0 \\
\frac{\partial J(\theta)}{\partial \theta_j} &amp;amp;=&amp;amp; \Big(\frac{1}{m} \sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)}\Big) + \frac{\lambda}{m}\theta_j &amp;amp;&amp;amp; \text{ for } j \ge 1
\end{align*}
$$&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Normal Equation&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="math"&gt;$$
\theta = (X^TX + \lambda
\begin{bmatrix} 
0 &amp;amp;&amp;amp;    &amp;amp;&amp;amp;   &amp;amp;&amp;amp;       \\
  &amp;amp;&amp;amp; 1  &amp;amp;&amp;amp;   &amp;amp;&amp;amp;       \\
  &amp;amp;&amp;amp;    &amp;amp;&amp;amp; \ddots &amp;amp;&amp;amp;  \\
  &amp;amp;&amp;amp;    &amp;amp;&amp;amp;   &amp;amp;&amp;amp;  1
\end{bmatrix}
)^{-1}X^Ty
$$&lt;/div&gt;
&lt;p&gt;we want &lt;span class="math"&gt;\(\lambda &amp;gt; 0\)&lt;/span&gt; so that the matrix is invertible.&lt;/p&gt;
&lt;h3 id="in-practice_1"&gt;In practice&lt;/h3&gt;
&lt;p&gt;Linear regression regularization implementation doesn’t differ from no-regularization
implementation in terms of matrices implementation technique. The following code chunk
demonstrates a way to calculate the cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; and the gradients (not gradient descent):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;J&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="o"&gt;)*(&lt;/span&gt;&lt;span class="nt"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;theta-y&lt;/span&gt;&lt;span class="o"&gt;).^&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;lambda&lt;/span&gt;&lt;span class="o"&gt;/(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="o"&gt;)*(&lt;/span&gt;&lt;span class="nt"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;end&lt;/span&gt;&lt;span class="o"&gt;).^&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;
&lt;span class="nt"&gt;G&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;lambda&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;G&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="nt"&gt;grad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;y&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;G&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;grad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;grad&lt;/span&gt;&lt;span class="o"&gt;(:);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="logistic-regression"&gt;Logistic regression&lt;/h2&gt;
&lt;p&gt;Logistic regression is a classification algorithm. It is better than the linear
regression because 1) linear regression classification result is higly impacted by the
outliers 2) linear regression result &lt;span class="math"&gt;\(h_\theta (x)\)&lt;/span&gt; can output value &lt;span class="math"&gt;\(&amp;gt;1\)&lt;/span&gt; or &lt;span class="math"&gt;\(&amp;lt;0\)&lt;/span&gt;, which
doesn’t fit with the nature of classification task.&lt;/p&gt;
&lt;p&gt;In contrast, as we will see, logistic regression output &lt;span class="math"&gt;\(0 \ge h_\theta (x) \le 1\)&lt;/span&gt;, which
can be intrepreted from probabily perspective.&lt;/p&gt;
&lt;h3 id="in-theory_2"&gt;In theory&lt;/h3&gt;
&lt;p&gt;Logistic regression hypothesis is &lt;/p&gt;
&lt;div class="math"&gt;$$
h_\theta(x) = g(\theta^Tx) \text{ where $g(z) = \frac{1}{1+e^{-z}}$}
$$&lt;/div&gt;
&lt;p&gt;This hypothesis can be intrepreted as the probability that &lt;span class="math"&gt;\(y = 1\)&lt;/span&gt; given &lt;span class="math"&gt;\(x\)&lt;/span&gt; and &lt;span class="math"&gt;\(\theta\)&lt;/span&gt;
(i.e. &lt;span class="math"&gt;\(h_\theta(x) = P(y = 1 | x;\theta)\)&lt;/span&gt;)&lt;/p&gt;
&lt;p&gt;In the linear regression, we have cost function \ref{eq:2}. However, 
&lt;span class="math"&gt;\(\text{cost}(h_\theta(x),y)\)&lt;/span&gt; cannot work for logistic regression because
&lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; is not convex. In order to make &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; convex, we have the following
&lt;span class="math"&gt;\(\text{cost}(h_\theta(x),y)\)&lt;/span&gt; for logistic regression&lt;/p&gt;
&lt;div class="math"&gt;$$
\text{cost}(h_\theta(x),y)=\left\{
                \begin{array}{ll}
                  -\log (h_\theta(x)) \text{ if } y = 1 \\
                  -\log (1 - h_\theta(x)) \text{ if } y = 0
                \end{array}
              \right.
$$&lt;/div&gt;
&lt;p&gt;We can rewrite the above equation as &lt;span class="math"&gt;\(\text{cost}(h_\theta(x),y) = -y \log(h_\theta(x)) - (1-y) \log (1-h_\theta(x))\)&lt;/span&gt;
and then the cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; is&lt;/p&gt;
&lt;div class="math"&gt;$$
J(\theta) = -\frac{1}{m}\sum_{i=1}^m \lbrack 
(y^{(i)}\log h_\theta(x^{(i)}) + (1-y^{(i)})\log(1-h_\theta(x^{(i)})))\rbrack
$$&lt;/div&gt;
&lt;p&gt;To minimize cost function &lt;span class="math"&gt;\(J(\theta)\)&lt;/span&gt; we can of course use gradient descent. Surprisingly,
the gradient descent for logistic regression is exactly the same as the gradient descent
for linear regression \ref{eq:3}. &lt;/p&gt;
&lt;p&gt;However, in the course, we directly use the &lt;code&gt;fminunc&lt;/code&gt; from Octave to do the optimization.
Internally, the function use advanced optimization technique that can avoid manually picking
&lt;span class="math"&gt;\(\alpha\)&lt;/span&gt; in gradient descent and find the optimal &lt;span class="math"&gt;\(\theta\)&lt;/span&gt; faster than gradient descent.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For multiclass classification problem, we have &lt;span class="math"&gt;\(h_\theta^{(i)}(x) = p(y=1 | x; \theta)\)&lt;/span&gt; where
&lt;span class="math"&gt;\(i = 1,2,3,...\)&lt;/span&gt;. Then, we can train a logistic regression classifier &lt;span class="math"&gt;\(h_\theta^{(i)}(x)\)&lt;/span&gt; for
each class &lt;span class="math"&gt;\(i\)&lt;/span&gt; to predict the probability that &lt;span class="math"&gt;\(y=i\)&lt;/span&gt;. On a new input &lt;span class="math"&gt;\(x\)&lt;/span&gt;, to make predication, pick
the class &lt;span class="math"&gt;\(i\)&lt;/span&gt; that gives highest &lt;span class="math"&gt;\(h_\theta^{(i)}(x)\)&lt;/span&gt;. We are going to predict &lt;span class="math"&gt;\(y\)&lt;/span&gt; with that value &lt;span class="math"&gt;\(i\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="in-practice_2"&gt;In practice&lt;/h3&gt;
&lt;p&gt;The implementation for cost function and gradient descent for logistic regression
should be no hard for us now:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;% cost function for logistic regression&lt;/span&gt;
&lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;'*&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sigmoid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;...&lt;/span&gt;&lt;span class="c"&gt;       &lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;'*&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sigmoid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;...&lt;/span&gt;&lt;span class="c"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;% gradient descent for logist regression&lt;/span&gt;
&lt;span class="n"&gt;grad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;'*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sigmoid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="logistic-regression-with-regularization"&gt;Logistic regression with regularization&lt;/h2&gt;
&lt;h3 id="in-theory_3"&gt;In theory&lt;/h3&gt;
&lt;p&gt;The cost function for regualarized logistic regression is following:&lt;/p&gt;
&lt;div class="math"&gt;$$
J(\theta) = -\frac{1}{m}\sum_{i=1}^m \lbrack 
(y^{(i)}\log h_\theta(x^{(i)}) + (1-y^{(i)})\log(1-h_\theta(x^{(i)})))\rbrack
+ \frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2
$$&lt;/div&gt;
&lt;p&gt;and the gradient descent looks exactly the same as the regualarized linear regression \ref{eq:5} and \ref{eq:6}. &lt;/p&gt;
&lt;h3 id="in-practice_3"&gt;In practice&lt;/h3&gt;
&lt;p&gt;The following code chunk shows the cost function and gradient descent for regularized
logistic regression:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;length&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;y&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;training&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;examples&lt;/span&gt;
&lt;span class="nt"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parameters&lt;/span&gt;

&lt;span class="nt"&gt;J&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;grad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;zeros&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;t&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nt"&gt;J&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="nt"&gt;-y&lt;/span&gt;&lt;span class="s1"&gt;'*log(sigmoid(X*theta)) ...&lt;/span&gt;
&lt;span class="s1"&gt;               -(1-y)'&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;1-sigmoid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="s1"&gt;'*theta(2: t);&lt;/span&gt;

&lt;span class="s1"&gt;grad(1) = (1/m * X'&lt;/span&gt;&lt;span class="o"&gt;*(&lt;/span&gt;&lt;span class="nt"&gt;sigmoid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;y&lt;/span&gt;&lt;span class="o"&gt;))(&lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;grad&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;*(&lt;/span&gt;&lt;span class="nt"&gt;sigmoid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;X&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;y&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;lambda&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;theta&lt;/span&gt;&lt;span class="o"&gt;)(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;t&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;We may need to do feature scaling when we work with gradient descent. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;We don’t penalize &lt;span class="math"&gt;\(\theta_0\)&lt;/span&gt;. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Machine Learning"></category><category term="machine learning"></category><category term="coursera"></category></entry><entry><title>Shell sort</title><link href="https://zhu45.org/posts/2017/May/01/shell-sort/" rel="alternate"></link><published>2017-05-01T21:33:00+08:00</published><updated>2017-05-01T21:33:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-05-01:/posts/2017/May/01/shell-sort/</id><summary type="html">&lt;p&gt;summary for shell sort&lt;/p&gt;</summary><content type="html">&lt;p&gt;Per the final paragraph of the &lt;a href="https://zhu45.org/posts/2017/Apr/24/simple-sorting-algorithms/"&gt;last post&lt;/a&gt;,
the algorithm needs to avoid doing adjacent swap (in other words, comparing elements that are distant) 
so that we can have the opportunity to remove more than one inversion for each swap, which
can break &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt; barrier. This is exactly what shellsort tries to achieve. &lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;Shellsort is referred as &lt;em&gt;diminishing increment&lt;/em&gt; sort: it works by swapping
non-adjacent elements; the distance between comparisons decreases as the 
algorithm runs until the last phase, in which adjacent elements are compared.&lt;/p&gt;
&lt;p&gt;Concretely, shellsort uses an increment sequence &lt;span class="math"&gt;\(h_1, h_2, \dots, h_t\)&lt;/span&gt; &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We start with &lt;span class="math"&gt;\(k=t\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sort all subsequences of elements that are &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; apart so that &lt;span class="math"&gt;\(A[i] \le A[i+h_k]\)&lt;/span&gt; for all i.
In other words, all elements spaced &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; apart are sorted. (&lt;span class="math"&gt;\(h_k\)&lt;/span&gt;-sort)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to the next smaller increment &lt;span class="math"&gt;\(h_{k-1}\)&lt;/span&gt; and repeat until &lt;span class="math"&gt;\(k = 1\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A popular but poor choice for incremenet sequence is: &lt;span class="math"&gt;\(h_t = \lfloor{N/2}\rfloor\)&lt;/span&gt; and
&lt;span class="math"&gt;\(h_k = \lfloor{h_{k+1}/2}\rfloor\)&lt;/span&gt; proposed by shell. &lt;/p&gt;
&lt;p&gt;Here is the shellsort using Shell’s increments &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;void&lt;/span&gt;
&lt;span class="n"&gt;shellSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="err"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j-increment&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j-increment&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is an example of the algorithm in action (using Shell’s increment sequence):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index        | 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  | 9  | 10 | 11 | 12 |
| original     | 81 | 94 | 11 | 96 | 12 | 35 | 17 | 95 | 28 | 58 | 41 | 75 | 15 |
|--------------|----|----|----|----|----|----|----|----|----|----|----|----|----|
| After 6-sort | 15 | 94 | 11 | 58 | 12 | 35 | 17 | 95 | 28 | 96 | 41 | 75 | 81 |
| After 3-sort | 15 | 12 | 11 | 17 | 41 | 28 | 58 | 94 | 35 | 81 | 95 | 75 | 96 |
| After 1-sort | 11 | 12 | 15 | 17 | 28 | 35 | 41 | 58 | 75 | 81 | 94 | 95 | 96 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="analysis"&gt;Analysis&lt;/h2&gt;
&lt;p&gt;The running time of shellsort depends on how we pick the increment sequence. MAW gives 
running time for two commonly-seen increment sequences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The worst-case running time of Shellsort, using Shell’s increments, is &lt;span class="math"&gt;\(\Theta(N^2)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;The worst-case running time of Shellsort, using Hibbard’s increments (&lt;span class="math"&gt;\(1,3,7, \dots, 2^k-1\)&lt;/span&gt;) &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;, is &lt;span class="math"&gt;\(\Theta(N^{3/2})\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The average case time is &lt;span class="math"&gt;\(O(N^{3/2})\)&lt;/span&gt; by using Hibbard’s increments. The worst case time
is the sequence when smallest elements in odd positions, largest in even positions (i.e. 2,11,4,12,6,13,8,14)
when we use shell’s sequence. Only last pass (i.e. &lt;span class="math"&gt;\(h_1 = 1\)&lt;/span&gt;) will do the work and it becomes 
an insertion sort with &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;. The best case can happen when we set the increment sequence to be 1
for any pass and we have a sorted array. In this case, we have &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Shellsort is good for up to &lt;span class="math"&gt;\(N \approx 10000\)&lt;/span&gt; and its simplcity makes it a favorite.&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;an &lt;span class="math"&gt;\(h_k\)&lt;/span&gt;-sorted array that is then &lt;span class="math"&gt;\(h_{k-1}\)&lt;/span&gt; sorted remains &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; sorted (why algorithm works).&lt;/li&gt;
&lt;li&gt;the action of an &lt;span class="math"&gt;\(h_k\)&lt;/span&gt;-sort is to perform an insertion sort on &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; independent subarrays with size about &lt;span class="math"&gt;\(N/h_k\)&lt;/span&gt; elements
(i.e. &lt;span class="math"&gt;\(h_k = 6\)&lt;/span&gt; then there are 6 subarrays(by index): {0,6,12}, {1,7}, {2,8}, {3,9}, {4,10}, {5,11}).&lt;/li&gt;
&lt;li&gt;a larger increment swaps more distant pairs (natural derivation of the above property).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MAW Chapter 7&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.duke.edu/courses/fall01/cps100/notes/sorting_cheat.txt"&gt;Sorting cheat sheet from Duke U.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://courses.cs.washington.edu/courses/cse373/01sp/Lect15.pdf"&gt;Lecture 15&lt;/a&gt; and
&lt;a href="https://courses.cs.washington.edu/courses/cse373/01sp/Lect16_2up.pdf"&gt;lecture 16&lt;/a&gt; from U.Washington&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web.mit.edu/1.124/LectureNotes/sorting.html"&gt;Notes from MIT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.rochester.edu/~brown/172/lectures/12_sort1/12sort1.html"&gt;Lecture from U.Rochester&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Any increment sequence will do as long as the last increment is 1 (i.e. &lt;span class="math"&gt;\(h_1 = 1\)&lt;/span&gt;).
However, choosing the increment is a practice of art: some choices dominate others. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;As suggested by the algorithm above, the general strategy to &lt;span class="math"&gt;\(h_k\)&lt;/span&gt;-sort is
for each position, &lt;span class="math"&gt;\(i\)&lt;/span&gt;, in &lt;span class="math"&gt;\(h_k, h_k+1, \dots, N-1,\)&lt;/span&gt; place the element in 
the correct spot among &lt;span class="math"&gt;\(i, i-h_k, i-2h_k\)&lt;/span&gt;, etc. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;The key difference between Hibbard’s increments and Shell’s increments is the adjacent
increments have no common factors. The problem with Shell’s increments is that
we keep comparing the same elements over and over again. We need to increment
so that different elements are in different passes. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="sorting"></category><category term="maw"></category></entry><entry><title>Simple sorting algorithms</title><link href="https://zhu45.org/posts/2017/Apr/24/simple-sorting-algorithms/" rel="alternate"></link><published>2017-04-24T21:33:00+08:00</published><updated>2017-04-24T21:33:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-24:/posts/2017/Apr/24/simple-sorting-algorithms/</id><summary type="html">&lt;p&gt;bubble sort, selection sort, and insertion sort&lt;/p&gt;</summary><content type="html">&lt;p&gt;This post summarizes three typical simple sorting algorithms: &lt;em&gt;bubble sort&lt;/em&gt;, 
&lt;em&gt;selection sort&lt;/em&gt;, and &lt;em&gt;insertion sort&lt;/em&gt;. In chapter 7, MAW mainly talks about 
&lt;em&gt;insertion sort&lt;/em&gt; but for the sake of completeness, I will include the other two as
well &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#bubble-sort"&gt;Bubble sort&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#concept"&gt;Concept&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#analysis"&gt;Analysis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#selection-sort"&gt;Selection sort&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#concept_1"&gt;Concept&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#analysis_1"&gt;Analysis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#insertion-sort"&gt;Insertion sort&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#concept_2"&gt;Concept&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#analysis_2"&gt;Analysis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#a-lower-bound-for-simple-sorting-algorithms"&gt;A Lower Bound for Simple Sorting Algorithms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#links-to-resources"&gt;Links to resources&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="bubble-sort"&gt;Bubble sort&lt;/h2&gt;
&lt;h3 id="concept"&gt;Concept&lt;/h3&gt;
&lt;p&gt;The idea for the bubble sort is to “bubble” larger elements to the end of array
by comparing &lt;span class="math"&gt;\(i\)&lt;/span&gt; and &lt;span class="math"&gt;\(i+1\)&lt;/span&gt;, and swapping if &lt;span class="math"&gt;\(A[i] &amp;gt; A[i+1]\)&lt;/span&gt;. We repeat this 
from the first to the end of unsorted part of the array.&lt;/p&gt;
&lt;p&gt;The following code demonstrates the actual algorithm&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;#define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SWAP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bubbleSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="err"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;passes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;thru&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;unsorted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;part&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j-1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SWAP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j-1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The key for the alogorithm is that we only do the “bubble up” operation for the
unsorted part. The following gives an example of the algorithm in action:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index    | 0  | 1  | 2  | 3  | 4  | 5  |
| original | 34 | 8  | 64 | 51 | 32 | 21 |
|----------|----|----|----|----|----|----|
| pass 0   | 8  | 34 | 51 | 32 | 21 | 64 |
| pass 1   | 8  | 34 | 32 | 21 | 51 | 64 |
| pass 2   | 8  | 32 | 21 | 34 | 51 | 64 |
| pass 3   | 8  | 21 | 32 | 34 | 51 | 64 |
| pass 4   | 8  | 21 | 32 | 34 | 51 | 64 |
| pass 5   | 8  | 21 | 32 | 34 | 51 | 64 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="analysis"&gt;Analysis&lt;/h3&gt;
&lt;p&gt;Bubble sort is stable and in place. The running time is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;, which is true
for both worst case and average case. &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; can be achieved in the best case, where
the array is sorted or mostly sorted (possible a few elements a place or two
away from their correct spots).&lt;/p&gt;
&lt;h2 id="selection-sort"&gt;Selection sort&lt;/h2&gt;
&lt;h3 id="concept_1"&gt;Concept&lt;/h3&gt;
&lt;p&gt;The idea for selection sort is to scan array and select small key and swap it with 
the first element of the array (i.e. &lt;span class="math"&gt;\(A[0]\)&lt;/span&gt;); scan remaining keys, select the smallest
and swap with the second element (i.e. &lt;span class="math"&gt;\(A[1]\)&lt;/span&gt;); repeat the whole process until last 
element is reached. In other words, after &lt;span class="math"&gt;\(i\)&lt;/span&gt;th pass, first &lt;span class="math"&gt;\(i\)&lt;/span&gt; elements are sorted and 
in proper position.&lt;/p&gt;
&lt;p&gt;Like the bubble sort, we divide the whole array into sorted part
and unsorted part: we start with unsorted array and keep the sorted array at the beginning.
Each time we scan the unsorted part of the array and decide which element should go next
into the sorted part. However, unlike bubble sort, we build the sorted part from the
beginning of the array (in bubble sort, we start with moving the largest element to 
the end of array).&lt;/p&gt;
&lt;p&gt;The following code demonstrates the actual algorithm&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;void&lt;/span&gt;
&lt;span class="n"&gt;selectionSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="err"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is an example of the algorithm in action:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index    | 0  | 1  | 2  | 3  | 4  | 5  |
| original | 34 | 8  | 64 | 51 | 32 | 21 |
|----------|----|----|----|----|----|----|
| pass 0   | 8  | 34 | 64 | 51 | 32 | 21 |
| pass 1   | 8  | 21 | 64 | 51 | 32 | 34 |
| pass 2   | 8  | 21 | 32 | 51 | 64 | 34 |
| pass 3   | 8  | 21 | 32 | 34 | 64 | 51 |
| pass 4   | 8  | 21 | 32 | 34 | 51 | 64 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="analysis_1"&gt;Analysis&lt;/h3&gt;
&lt;p&gt;The selection sort is NOT STABLE but in place. Selection sort is not sensitive
to the input and thus running time should be the same in best, average, and worst cases:
We go through &lt;span class="math"&gt;\(N-1\)&lt;/span&gt; passes with &lt;span class="math"&gt;\(N-1, \dots, 1\)&lt;/span&gt; comparisons, which is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Since selection sort is insensitive to the data, it’s good if we want to have our
sort routine always take the same time.&lt;/p&gt;
&lt;h2 id="insertion-sort"&gt;Insertion sort&lt;/h2&gt;
&lt;h3 id="concept_2"&gt;Concept&lt;/h3&gt;
&lt;p&gt;The idea for insertion sort is that we insert an as-yet-unprocessed record
into a sorted list of the records processed so far. In details, insertion sort
consists of &lt;span class="math"&gt;\(N-1\)&lt;/span&gt; passes. For pass &lt;span class="math"&gt;\(P = 1\)&lt;/span&gt; through &lt;span class="math"&gt;\(N-1\)&lt;/span&gt;, insertion sort ensures
that the elements in positions &lt;span class="math"&gt;\(0\)&lt;/span&gt; through &lt;span class="math"&gt;\(p\)&lt;/span&gt; are in sorted order. In pass &lt;span class="math"&gt;\(P\)&lt;/span&gt;,
we move the element in position &lt;span class="math"&gt;\(P\)&lt;/span&gt; left until its correct place is found among
the first &lt;span class="math"&gt;\(P+1\)&lt;/span&gt; elements.&lt;/p&gt;
&lt;p&gt;The following code demonstrates the actual algorithm&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;void&lt;/span&gt;
&lt;span class="n"&gt;insertionSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="err"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j-1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="c1"&gt;--)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j-1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is an example of the algorithm in action:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index    | 0  | 1  | 2  | 3  | 4  | 5  |
| original | 34 | 8  | 64 | 51 | 32 | 21 |
|----------|----|----|----|----|----|----|
| pass 1   | 8  | 34 | 64 | 51 | 32 | 21 |
| pass 2   | 8  | 34 | 64 | 51 | 32 | 21 |
| pass 3   | 8  | 34 | 51 | 64 | 32 | 21 |
| pass 4   | 8  | 32 | 34 | 51 | 64 | 21 |
| pass 5   | 8  | 21 | 32 | 34 | 51 | 64 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="analysis_2"&gt;Analysis&lt;/h3&gt;
&lt;p&gt;Due to the nested loops, the running time is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;, which can be achieved
when the input array is in reverse sorted order. In the best case, where 
the input array is already sorted, the running time is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;. For the average
case, the running time is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;. In fact, the bound is tight for both average case
and worst case: &lt;span class="math"&gt;\(\Theta (N^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In addition, insertion sort is stable and in place. Insertion sort is the most 
effectively used on input array with roughly &lt;span class="math"&gt;\(N &amp;lt; 20\)&lt;/span&gt; and for almost sorted array.&lt;/p&gt;
&lt;h2 id="a-lower-bound-for-simple-sorting-algorithms"&gt;A Lower Bound for Simple Sorting Algorithms&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An &lt;strong&gt;inversion&lt;/strong&gt; is a pair of elements in wrong order (i.e. &lt;span class="math"&gt;\(i &amp;lt; j\)&lt;/span&gt; but &lt;span class="math"&gt;\(A[i] &amp;gt; A[j]\)&lt;/span&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Simple sorting algorithms presented in this post swap adjacenet elements
(explicitly or implicitly) removes one inversion per swap. This makes the running
time proportional to number of inversions in array.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The average number of inversions in an array of &lt;span class="math"&gt;\(N\)&lt;/span&gt; distinct numbers is &lt;span class="math"&gt;\(N(N-1)/4\)&lt;/span&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Any algorithm that sorts by exchanging adjacent elements requires &lt;span class="math"&gt;\(\Omega (N^2)\)&lt;/span&gt; time
on average. This is due to the fact that each adjacent swap removes only one inversion.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can tell, to break &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt; barrier, we must remove more than one inversion
for each swap. Adjacent elements swap will certainly not help us to achieve this goal.
The idea is that we try to swap the elements that are far apart and hopefully we can 
remove more than one inversion for each swap. Shell sort is the first algorithm
to break &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt; running time. I’ll talk about it in my next post.&lt;/p&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MAW Chapter 7&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.duke.edu/courses/fall01/cps100/notes/sorting_cheat.txt"&gt;Sorting cheat sheet from Duke U.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://courses.cs.washington.edu/courses/cse373/01sp/Lect15.pdf"&gt;Lecture 15&lt;/a&gt; from U.Washington&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web.mit.edu/1.124/LectureNotes/sorting.html"&gt;Notes from MIT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.rochester.edu/~brown/172/lectures/12_sort1/12sort1.html"&gt;Lecture from U.Rochester&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;a href="https://youtu.be/8Kp-8OGwphY"&gt;bubble sort video&lt;/a&gt;, &lt;a href="https://youtu.be/f8hXR_Hvybo"&gt;selection sort video&lt;/a&gt;, 
&lt;a href="https://youtu.be/DFG-XuyPYUQ"&gt;insertion sort video&lt;/a&gt; and 
&lt;a href="https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html"&gt;this animation&lt;/a&gt;
can help you understand the concept. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="sorting"></category><category term="maw"></category></entry><entry><title>Introducing the "Andrew Ng's ML course study notes"</title><link href="https://zhu45.org/posts/2017/Apr/21/introducing-the-andrew-ngs-ml-course-study-notes/" rel="alternate"></link><published>2017-04-21T23:48:00+08:00</published><updated>2017-04-21T23:48:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-21:/posts/2017/Apr/21/introducing-the-andrew-ngs-ml-course-study-notes/</id><summary type="html">&lt;p&gt;Let the battle begins :)&lt;/p&gt;</summary><content type="html">&lt;p&gt;I finally enrolled in Andrew Ng’s machine learning course on 
&lt;a href="https://www.coursera.org/learn/machine-learning/home/welcome"&gt;Coursera&lt;/a&gt;. Here is 
my expectation for this course:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get a fun intro to machine learning field. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I studied mathematics, statistics, and took AI course when I was an undergraduate
but I never had an intro to ML formally. All the work I have done so far has
a very strong relationship with ML but they don’t really target on ML specifically.
So, I think Andrew Ng’s ML course is probably a great intro to this field.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In preparation for my graduate studies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m thinking of pursuing a research career in NLP and robotics but I need to some
ground work to see if they are actually fun like I’m picturing in my mind. In addition,
before actually taking graduate level related courses, there might be some gaps I
need to fill out. So I think Andrew Ng’s course may be a greate bridge course
to get me warm up for the serious graduate level ML studies.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take a break from Algo studies and keep myself motivated.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m currently working on a reading project to finish MAW by the end of this September.
The progress so far is on track and I’m having a lot of fun with the book. However,
sometimes, I want to experience some different flavor of dishes and take a break. In 
addition, I’m thinking of the next reading project I’m going to do. It’s highly likely
going to be a book in linear algebra. I have taken linear algebra before in the college
but I found the subject can become quite boring very soon if you don’t have specific
problems or needs want to address. Hopefully, Andrew Ng’s course will help me to
find some motivation to study linear algebra well.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start to make résumé ML-ish&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’m working in DB field but I always want to do ML by nature judged by my performance
in the ML-related courses. Taking ML course on coursera and having a nice badge on
my LinkedIn may greatly help me to market my ML expertise in the future?&lt;/p&gt;
&lt;p&gt;My current plan is to finish the coursera version first, and then move on to 
&lt;a href="http://cs229.stanford.edu/materials.html"&gt;CS229&lt;/a&gt; version if time permits. 
I want to take an agile approach to this material by doing iteratively build-up.&lt;/p&gt;</content><category term="Machine Learning"></category><category term="machine learning"></category><category term="coursera"></category></entry><entry><title>Sorting prelim</title><link href="https://zhu45.org/posts/2017/Apr/18/sorting-prelim/" rel="alternate"></link><published>2017-04-18T10:03:00+08:00</published><updated>2017-04-18T10:03:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-18:/posts/2017/Apr/18/sorting-prelim/</id><summary type="html">&lt;p&gt;Prelim for sorting&lt;/p&gt;</summary><content type="html">&lt;p&gt;Chapter 7: Sorting will have some rigorous analysis of the sorting algorithms
(no wonder as suggested by the title of the book). Some meta-concepts related with
sorting appeard at the very beginning of the chapter. I usually push them to the
end-chapter summary post but this time I decide to do a writeup beforehand because 
I find it is really hard to talk about various sorting schemes without setting up some
ground concepts first.&lt;/p&gt;
&lt;h2 id="definitions"&gt;Definitions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Sorting problem: Given an array &lt;span class="math"&gt;\(A\)&lt;/span&gt;, output &lt;span class="math"&gt;\(A\)&lt;/span&gt; such that: 
  For any &lt;span class="math"&gt;\(i\)&lt;/span&gt; and &lt;span class="math"&gt;\(J\)&lt;/span&gt;, if &lt;span class="math"&gt;\(i &amp;lt; j\)&lt;/span&gt;, then &lt;span class="math"&gt;\(A[i] \le A[j]\)&lt;/span&gt;.&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sorting algorithm using comparison operators (i.e &lt;span class="math"&gt;\(&amp;lt;, &amp;gt;, =\)&lt;/span&gt;) is known as
&lt;strong&gt;comparison-based sorting&lt;/strong&gt;. Another major type is called &lt;strong&gt;counting sort&lt;/strong&gt; (i.e. Radix sort).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the entire sort can be done in main memory (i.e number of elements is relatively small, usually less than a million), we call it &lt;strong&gt;internal sorting&lt;/strong&gt;. By the contrast,
if the data is on the disk, we call it &lt;strong&gt;external sorting&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An algorithm requires &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; extra space is known as an &lt;strong&gt;in place&lt;/strong&gt; sorting algorithm.&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A sorting algorithm is &lt;strong&gt;stable&lt;/strong&gt; &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt; if elements with equal keys are left in the same
order as they occur in the input. In other words, we can ask ourself the question:
Does it rearrange the order of input data records which have the same key value
(duplicates)? If the answer is No, then the sorting algorithm is &lt;em&gt;stable&lt;/em&gt;.
One example is that Phone book is sorted by name. 
Now let’s sort the book by country - is the list still sorted by name within each country?
As you can tell, it is an extremely important property for databases.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There will be three kinds of running time mentioned in the sorting analysis:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;average case time&lt;/em&gt;: given an arbitrary input, what do we expect the running time
to be.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;worst case time&lt;/em&gt;: for a particular degenerate case, how bad will the algorithm
perform.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;best case time&lt;/em&gt;: for a particularly benevolent input case, what is the best case 
performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MAW Chapter 7&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.duke.edu/courses/fall01/cps100/notes/sorting_cheat.txt"&gt;Sorting cheat sheet from Duke U.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://courses.cs.washington.edu/courses/cse373/01sp/Lect15.pdf"&gt;Lecture material from U.Washington&lt;/a&gt; and
&lt;a href="http://web.mit.edu/1.124/LectureNotes/sorting.html"&gt;MIT&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Here, for the input, we are given an array &lt;span class="math"&gt;\(A\)&lt;/span&gt; of data records, each with
a key (which can be an integer, character, string, etc) as long as the following
condition can be met: 1. There is an ordering on the set of possible keys 2. We can compare any two keys using &lt;span class="math"&gt;\(&amp;lt;, &amp;gt;, =\)&lt;/span&gt; &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Under the context of the sorting, we may ask: Does the sorting algorithm require extra
memory to sort the collection of items? Do we need to copy and temporarily store some 
subset of the keys/data records? &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;When we evaluate the performance of a sorting algorithm, we usually evaluate it
from three perspectives: &lt;em&gt;running time&lt;/em&gt;, &lt;em&gt;memory requirements (aka space)&lt;/em&gt;, and &lt;em&gt;stability&lt;/em&gt;. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="sorting"></category><category term="maw"></category></entry><entry><title>MAW Chapter 7: Sorting writing questions</title><link href="https://zhu45.org/posts/2017/Apr/15/maw-chapter-7-sorting-writing-questions/" rel="alternate"></link><published>2017-04-15T23:54:00+08:00</published><updated>2017-04-15T23:54:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-15:/posts/2017/Apr/15/maw-chapter-7-sorting-writing-questions/</id><summary type="html">&lt;p&gt;My solutions to selected problems in MAW Chapter 7&lt;/p&gt;</summary><content type="html">&lt;h2 id="solutions"&gt;Solutions&lt;/h2&gt;
&lt;p&gt;including: MAW 7.1, 7.2, 7.3, 7.4, 7.5.a, 7.9, 7.10, 7.11, 7.12, 7.13&lt;/p&gt;
&lt;h3 id="maw-71"&gt;MAW 7.1&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Sort the sequence 3,1,4,1,5,9,2,6,5 using insertion sort.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index    | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| original | 3 | 1 | 4 | 1 | 5 | 9 | 2 | 6 | 5 |
|----------|---|---|---|---|---|---|---|---|---|
| pass 1   | 1 | 3 | 4 | 1 | 5 | 9 | 2 | 6 | 5 |
| pass 2   | 1 | 3 | 4 | 1 | 5 | 9 | 2 | 6 | 5 |
| pass 3   | 1 | 1 | 3 | 4 | 5 | 9 | 2 | 6 | 5 |
| pass 4   | 1 | 1 | 3 | 4 | 5 | 9 | 2 | 6 | 5 |
| pass 5   | 1 | 1 | 3 | 4 | 5 | 9 | 2 | 6 | 5 |
| pass 6   | 1 | 1 | 2 | 3 | 4 | 5 | 9 | 6 | 5 |
| pass 7   | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 9 | 5 |
| pass 8   | 1 | 1 | 2 | 3 | 4 | 5 | 5 | 6 | 9 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="maw-72"&gt;MAW 7.2&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;What is the running time of insertion sort if all keys are equal?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you take a look at the code on p. 220, you can see that inner for loop checks
&lt;code&gt;A[j-1] &amp;gt; tmp&lt;/code&gt; and it will fail immediately. Thus, the running time is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="maw-73"&gt;MAW 7.3&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose we exchange elements &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt;, which were originally
out of order. Prove that at least 1 and at most &lt;span class="math"&gt;\(2k-1\)&lt;/span&gt; inversions are removed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The inversion that existed between &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt; is removed. This shows 
at least one inversion is removed. Now let’s consider &lt;span class="math"&gt;\(A[i], A[i+1], \dots, A[i+k-1], A[i+k]\)&lt;/span&gt;,
Suppose &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; is greater than &lt;span class="math"&gt;\(A[i+1], \dots, A[i+k]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt; is smaller than
&lt;span class="math"&gt;\(A[i], \dots, A[i+k-1]\)&lt;/span&gt;. In this case, by swapping &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt;, we fix 
&lt;span class="math"&gt;\(2k-1\)&lt;/span&gt; inversions (&lt;span class="math"&gt;\(-1\)&lt;/span&gt; is that &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; greater than &lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt; smaller
than &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; points to the same inversion).&lt;/p&gt;
&lt;p&gt;Another way to think about &lt;span class="math"&gt;\(2k-1\)&lt;/span&gt; is that for each of the &lt;span class="math"&gt;\(k-1\)&lt;/span&gt; elements 
&lt;span class="math"&gt;\(A[i+1], A[i+2], \dots, A[i+k-1]\)&lt;/span&gt;, at most two inversions can be removed by exchange.
For instance, for &lt;span class="math"&gt;\(A[i+1]\)&lt;/span&gt;, two inversions are &lt;span class="math"&gt;\(A[i]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[i+1]\)&lt;/span&gt;, and &lt;span class="math"&gt;\(A[i+1]\)&lt;/span&gt; and
&lt;span class="math"&gt;\(A[i+k]\)&lt;/span&gt; (i.e. for sequence 10,4,3, by swapping 10 and 3, we remove inversion {10,4}
and {4,3}). Thus, a maximum of &lt;span class="math"&gt;\(2(k-1)+1 = 2k-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="maw-74"&gt;MAW 7.4&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Show the result of running Shellsort on the input 9,8,7,6,5,4,3,2,1 using the
increments {1,3,7}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index        | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| original     | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
|--------------|---|---|---|---|---|---|---|---|---|
| after 7-sort | 2 | 1 | 7 | 6 | 5 | 4 | 3 | 9 | 8 |
| after 3-sort | 2 | 1 | 4 | 3 | 5 | 7 | 6 | 9 | 8 |
| after 1-sort | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="maw-75a"&gt;MAW 7.5.a&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;What is the running time of Shellsort using the two-increment sequence {1,2}?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The answer is &lt;span class="math"&gt;\(\Theta(N^2)\)&lt;/span&gt;. Let’s first show the lower bound. By the conclusion
of 7.3, we know that The 2-sort removes at most only three (i.e. &lt;span class="math"&gt;\(k=2\)&lt;/span&gt;) inversions
at a time. In addition, a pass with increment &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; consists of &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; insertion sorts
of about &lt;span class="math"&gt;\(N/h_k\)&lt;/span&gt; elements. Then, by theorem 7.2, we know that the algorithm 
is &lt;span class="math"&gt;\(\Omega(N^2)\)&lt;/span&gt;. By the same argument, the 2-sort is two insertion sorts of size &lt;span class="math"&gt;\(N/2\)&lt;/span&gt;,
so the cost of that pass is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;. The 1-sort is also &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;, so the upper bound
for the algorithm is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt;. &lt;/p&gt;
&lt;h3 id="maw-79"&gt;MAW 7.9&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Determine the running time (i.e. number of swaps) of Shellsort for &lt;/p&gt;
&lt;p&gt;a. sorted input&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class="math"&gt;\(O(N \log N)\)&lt;/span&gt;. No exachanges acutally done in each each pass but we will still
need to go through the second for loop, which indicates that each pass takes 
&lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;. There are total &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; passes and the answer follows.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;b. reverse-ordered input&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class="math"&gt;\(O(N \log N)\)&lt;/span&gt;. It is easy to show that after an &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; sort, no element is farther
than &lt;span class="math"&gt;\(h_k\)&lt;/span&gt; from its rightful position. Thus, if the increments satisfy &lt;span class="math"&gt;\(h_{k+1} \le ch_k\)&lt;/span&gt;
for a constant &lt;span class="math"&gt;\(c\)&lt;/span&gt;, which implies &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; increments, then the bound follows.&lt;/p&gt;
&lt;p&gt;However, one cannot talk about shellsort without specifying the increment sequence.
If we assume the shell sequence (i.e. &lt;span class="math"&gt;\(N/2, N/4, \dots, 2, 1\)&lt;/span&gt;), then the running time
is &lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt; as suggested by &lt;a href="https://www.cs.rochester.edu/~brown/172/exams/2ndmidterm_ans_13.pdf"&gt;this answer&lt;/a&gt;,
which I’ll copy below for future reference.&lt;/p&gt;
&lt;p&gt;Shellsort is just a bunch of insertion sorts. For a given increment &lt;span class="math"&gt;\(I\)&lt;/span&gt;, there will
be &lt;span class="math"&gt;\(I\)&lt;/span&gt; subarrays to sort by insertion, each of length &lt;span class="math"&gt;\(N/I\)&lt;/span&gt;. We know that insertion
sort requires time &lt;span class="math"&gt;\(O(m^2)\)&lt;/span&gt; to sort a reverse-sorted array of length &lt;span class="math"&gt;\(m\)&lt;/span&gt;. Here, &lt;span class="math"&gt;\(m\)&lt;/span&gt;
will be (&lt;span class="math"&gt;\(N/I\)&lt;/span&gt;) for each subarray. Thus one subarray will cost &lt;span class="math"&gt;\((N/I)^2\)&lt;/span&gt; to sort. 
There are &lt;span class="math"&gt;\(I\)&lt;/span&gt; subarrays, so the total cost will be &lt;span class="math"&gt;\(I * (N/I)^2 = N^2/I\)&lt;/span&gt;. But that 
is the cost just for a single increment. The total time for all of the iterations must be
&lt;span class="math"&gt;\(N^2/(N/2) + N^2/(N/4) + N^2/(N/8) + \dots + N^2/2 + N^2/1 = 2N + 4N + \dots + N^2/2 + N^2/1\)&lt;/span&gt; .
If we factor out an &lt;span class="math"&gt;\(N\)&lt;/span&gt;, we get &lt;span class="math"&gt;\(N(2+4+\dots+N/2+N)\)&lt;/span&gt; . In parenthesis is the sum of powers of 
2 from 2 to &lt;span class="math"&gt;\(N\)&lt;/span&gt;, which is approximately equalt to &lt;span class="math"&gt;\(2N\)&lt;/span&gt;. Therefore, the total cost
is &lt;span class="math"&gt;\(N(2N) = 2N^2 = O(N^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="maw-710"&gt;MAW 7.10&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Do either of the following modifications to the Shellsort routine coded in 
Fig. 7.4 affect the worst case running time?&lt;/p&gt;
&lt;p&gt;a. Before line 2, subtract one from &lt;code&gt;Increment&lt;/code&gt; if it is even.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The key improvement in terms of the worst case running time lies in the increment
sequence. As suggested on p.224,225, we improve the worst time running time from
&lt;span class="math"&gt;\(O(N^2)\)&lt;/span&gt; to &lt;span class="math"&gt;\(O(N^{3/2})\)&lt;/span&gt; by changing the increment sequence into the sequence that
consecutive increments have no common factors. &lt;/p&gt;
&lt;p&gt;If we follow the modification indicated by this question, it is still possible
to have a case that we will have consecutive increments to share a common factor.
For instance, if we sort an array with size &lt;span class="math"&gt;\(N = 45\)&lt;/span&gt;, then with the modification,
the increment sequence will be &lt;span class="math"&gt;\(45, 21 (22-1), 9, 3, 1\)&lt;/span&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;b. Before line 2, add one to &lt;code&gt;Increment&lt;/code&gt; if it is even.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this case, conseuctive increments are relatively prime and by the argument in 
the proof of theorem 7.4, we can have the worst case running time &lt;span class="math"&gt;\(O(N^{3/2})\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="maw-711"&gt;MAW 7.11&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Show how heapsort processes the input 142, 543, 123, 65, 453, 879, 572, 434, 111, 242, 
811, 102.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The input is read in as it appears in the question. Then, we first build the heap with 
the result looks like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;879&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class="math"&gt;\(879\)&lt;/span&gt; is removed from the heap and placed at the end. We’ll put &lt;em&gt;|&lt;/em&gt; to separate the elements
that are sorted and not part of the heap. &lt;span class="math"&gt;\(102\)&lt;/span&gt; is placed in the hole and bubbled down, obtaining&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;continuing the process, we obtain&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;65&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;142&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;242&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;434&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;543&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;572&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;811&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;879&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="maw-712"&gt;MAW 7.12&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;a. What is the running time of heapsort for presorted input?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Still &lt;span class="math"&gt;\(O(N\log N)\)&lt;/span&gt;. Heapsort uses at least (roughly) 
&lt;span class="math"&gt;\(N\log N\)&lt;/span&gt; comparisons on any input, so there are no particularly
good inputs.&lt;/p&gt;
&lt;h3 id="maw-713"&gt;MAW 7.13&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Sort 3,1,4,1,5,9,2,6 using mergesort&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First the sequence {3,1,4,1} is sorted. To do this, the sequence {3,1}
is sorted. This involves sorting {3} and {1}, which are base cases, and
merging the result to obtain {1,3}. The sequence {4,1} is likewise sorted into
{1,4}. Then these two sequences are merged to obtain {1,1,3,4}. The second
half is sorted similarly, eventually obtaining {2,5,6,9}. The merge 
result is then easily computed as {1,1,2,3,4,5,6,9}.&lt;/p&gt;
&lt;h3 id="maw-715"&gt;MAW 7.15&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Determine the running time of mergesort for
a. sorted input
b. reverse-ordered input
c. random input&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The running time for mergesort is &lt;span class="math"&gt;\(O(N \log N)\)&lt;/span&gt; regardless of the input pattern.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="sorting"></category><category term="proof"></category><category term="math"></category><category term="maw"></category></entry><entry><title>MAW: Chapter 6 Reflection</title><link href="https://zhu45.org/posts/2017/Apr/09/maw-chapter-6-reflection/" rel="alternate"></link><published>2017-04-09T10:45:00+08:00</published><updated>2017-04-09T10:45:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-09:/posts/2017/Apr/09/maw-chapter-6-reflection/</id><summary type="html">&lt;p class="first last"&gt;An overview summary of MAW Chapter 6&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="reflection"&gt;
&lt;h2&gt;Reflection&lt;/h2&gt;
&lt;p&gt;In chapter 6, we learn about the priority queue ADT. We assume each item has
a "priority" and the ADT allows us to insert the element into the queue and
get the element with "highest" priority from the queue. The model looks like&lt;/p&gt;
&lt;img alt="priority queue ADT" class="img-responsive" src="/images/priority-queue-ADT.PNG"/&gt;&lt;p&gt;and the big picture we have studied so far becomes:&lt;/p&gt;
&lt;img alt="ADT overview" class="img-responsive" src="/images/ADT.PNG"/&gt;&lt;p&gt;In order to support two operations required by the model, we propose four new
implmentations. &lt;a class="reference external" href="https://zhu45.org/posts/2017/Apr/02/binary-heap/"&gt;Binary heap&lt;/a&gt; is
the most commonly-seen one. Insert can be done in &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; in the worst
case and constant on average. DeleteMin can be done in &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;. However,
it has natural drawback in supporting merge operation, which is needed when we
want to merge two heaps into one. This leads to the
&lt;a class="reference external" href="https://zhu45.org/posts/2017/Apr/04/leftist-heap/"&gt;leftist heap&lt;/a&gt;. Leftist heap
supports all three operations (insert, DeleteMin, merge) efficiently but we
needs to maintain extra information in the node and we need to do extra test
during merge in order to maintain the leftist heap property.
To better solve these two little disadvantages, we propose
&lt;a class="reference external" href="https://zhu45.org/posts/2017/Apr/05/skew-heap/"&gt;skew heap&lt;/a&gt;, which has
no restriction on the tree structure at all while still enjoying the efficiency of operations
in amortized time. However, there is still room for improvement because
both leftist heap and skew heap cannot support constant on average insertion like
binary heap does. This is why we propose a new structure called
&lt;a class="reference external" href="https://zhu45.org/posts/2017/Apr/08/binomial-queue/"&gt;binomial queue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are many applications of priority queues:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Operating system task scheduler&lt;/li&gt;
&lt;li&gt;Forward network packets in order of urgency&lt;/li&gt;
&lt;li&gt;Select most frequent symbols for data compression&lt;/li&gt;
&lt;li&gt;Sorting&lt;/li&gt;
&lt;li&gt;Implementation for greedy algorithms&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="left-out"&gt;
&lt;h2&gt;Left Out&lt;/h2&gt;
&lt;p&gt;Some material I left out when I work through this chapter:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;6.9.c, 6.10, 6.12, 6.20, 6.21, 6.30, 6.32, 6.33, 6.34, 6.35, 6.36&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="reference"&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;MAW Chapter 6&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture4.pdf"&gt;https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture4.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"></category><category term="maw"></category><category term="heaps"></category></entry><entry><title>Binomial queue</title><link href="https://zhu45.org/posts/2017/Apr/08/binomial-queue/" rel="alternate"></link><published>2017-04-08T23:33:00+08:00</published><updated>2017-04-08T23:33:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-08:/posts/2017/Apr/08/binomial-queue/</id><summary type="html">&lt;p&gt;Summary for binomial queue&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;binomial queue&lt;/em&gt; part in MAW Chapter 6.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;We want to have a data structure that support merging, insertion, and deleteMin
in &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time per operation, and at the same time, like binary heap, we 
want to have insertion takes constant time on average. The latter part is not possible
with skew heap or leftist heap. &lt;/p&gt;
&lt;p&gt;The data structure we have is called &lt;em&gt;binomial queue&lt;/em&gt;.&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;Binomial queues is a collection of heap-ordered trees. Each of the heap-ordered
trees is called a &lt;em&gt;binomial tree&lt;/em&gt; with the following constraints:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is at most one binomial tree of every height.&lt;/li&gt;
&lt;li&gt;A binomial tree of height 0 is a one-node tree; a binomial tree, &lt;span class="math"&gt;\(B_k\)&lt;/span&gt;, of 
height &lt;span class="math"&gt;\(k\)&lt;/span&gt; is formed by attaching a binomial tree, &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt;, to the root of another
binomial tree, &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The picture below shows a binomial queue consisting of six elements
with two binomial trees &lt;span class="math"&gt;\(B_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(B_2\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue example" class="img-responsive" src="/images/binomial-queue.PNG"/&gt;&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A binomial tree &lt;span class="math"&gt;\(B_k\)&lt;/span&gt;, consists of a root with children &lt;span class="math"&gt;\(B_0, B_1, \dots, B_{k-1}\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Binomial trees of height &lt;span class="math"&gt;\(k\)&lt;/span&gt; have exactly &lt;span class="math"&gt;\(2^k\)&lt;/span&gt; nodes&lt;/li&gt;
&lt;li&gt;The number of nodes at depth &lt;span class="math"&gt;\(d\)&lt;/span&gt; is the binomial coefficient &lt;span class="math"&gt;\({k \choose d}\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;A priority queue of any size can be represented by a collection of binomial trees.
For instances, a priority queue of size 13 could be represented by &lt;span class="math"&gt;\(B_3, B_2, B_0\)&lt;/span&gt; 
( &lt;span class="math"&gt;\(13 = 2^3 + 2^2 + 2^0\)&lt;/span&gt; ). Thus, we can write this representation as &lt;span class="math"&gt;\(1101\)&lt;/span&gt;, which not 
only represents &lt;span class="math"&gt;\(13\)&lt;/span&gt; in binary but also represents the fact that &lt;span class="math"&gt;\(B_3, B_2, B_0\)&lt;/span&gt;
are present and &lt;span class="math"&gt;\(B_1\)&lt;/span&gt; is not.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="operations"&gt;Operations&lt;/h2&gt;
&lt;h3 id="merge"&gt;Merge&lt;/h3&gt;
&lt;p&gt;The merge is performed by essentially adding the two queues together. Let’s illustrate
through merging two binomial queues &lt;span class="math"&gt;\(H_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(H_2\)&lt;/span&gt; shown below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue merge 01" class="img-responsive" src="/images/binomial-queue-merge-01.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;If you will, &lt;span class="math"&gt;\(H_1\)&lt;/span&gt; can be represented as &lt;span class="math"&gt;\(0110_{2}\)&lt;/span&gt; and &lt;span class="math"&gt;\(H_2\)&lt;/span&gt; can be represented as
&lt;span class="math"&gt;\(0111_{2}\)&lt;/span&gt;. Thus, merge is just adding two binary number together, and we have
&lt;span class="math"&gt;\(1101_2\)&lt;/span&gt;. This implies that our final result contains &lt;span class="math"&gt;\(B_0, B_2, B_3\)&lt;/span&gt;. The actual
merge step is implied by the binomial tree constraint mentioned above:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A binomial tree of height 0 is a one-node tree; a binomial tree, &lt;span class="math"&gt;\(B_k\)&lt;/span&gt;, of 
height &lt;span class="math"&gt;\(k\)&lt;/span&gt; is formed by attaching a binomial tree, &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt;, to the root of another
binomial tree, &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thus merge of the two &lt;span class="math"&gt;\(B_1\)&lt;/span&gt; trees in &lt;span class="math"&gt;\(H_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(H_2\)&lt;/span&gt; looks like:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue merge 02" class="img-responsive" src="/images/binomial-queue-merge-02.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;and the final result of merging looks like:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue merge 03" class="img-responsive" src="/images/binomial-queue-merge-03.PNG"/&gt;&lt;/p&gt;
&lt;h3 id="insertion"&gt;Insertion&lt;/h3&gt;
&lt;p&gt;Insertion is just a special case of merging, since we merely create a one-node tree
and perform a merge.&lt;/p&gt;
&lt;h3 id="deletemin"&gt;DeleteMin&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;find the binomial tree with the smallest root. Let this tree be &lt;span class="math"&gt;\(B_k\)&lt;/span&gt;, and let the original priority queue be &lt;span class="math"&gt;\(H\)&lt;/span&gt;. &lt;/li&gt;
&lt;li&gt;Remove the binomial tree &lt;span class="math"&gt;\(B_k\)&lt;/span&gt; from the forest of trees in &lt;span class="math"&gt;\(H\)&lt;/span&gt;, forming the new binomial queue &lt;span class="math"&gt;\(H'\)&lt;/span&gt;. &lt;/li&gt;
&lt;li&gt;Remove the root of &lt;span class="math"&gt;\(B_k\)&lt;/span&gt;, creating binomial trees &lt;span class="math"&gt;\(B_0, B_1, \dots, B_{k-1}\)&lt;/span&gt;, which collectively form priority queue &lt;span class="math"&gt;\(H''\)&lt;/span&gt;. &lt;/li&gt;
&lt;li&gt;merge &lt;span class="math"&gt;\(H'\)&lt;/span&gt; and &lt;span class="math"&gt;\(H''\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Suppose we perform a DeleteMin on &lt;span class="math"&gt;\(H_3\)&lt;/span&gt; from above. The minimum root is 12, and we have 
&lt;span class="math"&gt;\(H'\)&lt;/span&gt; and &lt;span class="math"&gt;\(H''\)&lt;/span&gt; below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue deleteMin 01" class="img-responsive" src="/images/binomial-queue-deleteMin-01.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue deleteMin 02" class="img-responsive" src="/images/binomial-queue-deleteMin-02.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;and our final result is &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binomial queue deleteMin 03" class="img-responsive" src="/images/binomial-queue-deleteMin-03.PNG"/&gt;&lt;/p&gt;
&lt;h2 id="runtime-analysis"&gt;Runtime analysis&lt;/h2&gt;
&lt;h3 id="merge_1"&gt;Merge&lt;/h3&gt;
&lt;p&gt;Since merging two binomial trees takes constant time with almost any reasonable
implementation, and there are &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; binomial trees (think of representing
the size of priority queue in terms of binary, and we need to do &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; division),
the merge takes &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time.&lt;/p&gt;
&lt;h3 id="insertion_1"&gt;Insertion&lt;/h3&gt;
&lt;p&gt;The worst-case time of this operation is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;. However, this actually can be
constant on average. Details see MAW p.205.&lt;/p&gt;
&lt;h3 id="deletemin_1"&gt;DeleteMin&lt;/h3&gt;
&lt;p&gt;We take &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time to find the tree containing the minimum element. We take
constant time to create the queues &lt;span class="math"&gt;\(H'\)&lt;/span&gt; and &lt;span class="math"&gt;\(H''\)&lt;/span&gt;. Merging these
two queues takes &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time and thus, the operation overall takes &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 6&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;For actual implementation details, please see MAW p. 208 - 211. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="heaps"></category><category term="maw"></category></entry><entry><title>Skew heap</title><link href="https://zhu45.org/posts/2017/Apr/05/skew-heap/" rel="alternate"></link><published>2017-04-05T23:33:00+08:00</published><updated>2017-04-05T23:33:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-05:/posts/2017/Apr/05/skew-heap/</id><summary type="html">&lt;p&gt;Summary for skew heap&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;skew heap&lt;/em&gt; part in MAW Chapter 6.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Like the relation between splay trees and AVL trees, we want to have 
&lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; amortized cost per operation. In addition, we don’t want
to have any auxiliary information stored at the nodes. In other words,
we want to trade strict &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; operation for less space we need 
to use for the data structure. In this case,
like splay trees to AVL trees, we have Skew heaps to leftist heaps.&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;Skew heaps are binary trees with heap order, but there is no structural constraint
on these trees. This means that we don’t need the binary tree to be complete 
(i.e. binary heap) or left heavy (i.e. leftist heap).&lt;/p&gt;
&lt;p&gt;In addition, we don’t store &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; information in the node.&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A perfectly balanced tree forms if the keys &lt;span class="math"&gt;\(1\)&lt;/span&gt; to &lt;span class="math"&gt;\(2^k-1\)&lt;/span&gt; are inserted in order
into an initially empty skew heap.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="operations"&gt;Operations&lt;/h2&gt;
&lt;p&gt;Skew heap is extremely similar with &lt;a href="https://zhu45.org/posts/2017/Apr/04/leftist-heap/"&gt;leftist heap&lt;/a&gt; 
in terms of &lt;code&gt;merge&lt;/code&gt; operation. There is only one difference: for leftist heap, we check to see whether the 
left and right children satisfy the leftist heap order property and swap them
if they do not. However, for skew heaps, the swap is unconditional. In other words,
we &lt;strong&gt;always&lt;/strong&gt; swap the left &amp;amp; right subtrees at each step of merge. &lt;/p&gt;
&lt;p&gt;In the below example, we want to merge two skew heaps &lt;span class="math"&gt;\(H_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(H_2\)&lt;/span&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="skew heap 01" class="img-responsive" src="/images/skew-heap-01.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;Then, we get the following result of merging &lt;span class="math"&gt;\(H_2\)&lt;/span&gt; with &lt;span class="math"&gt;\(H_1\)&lt;/span&gt;‘s right subheap:&lt;/p&gt;
&lt;p&gt;&lt;img alt="skew heap 02" class="img-responsive" src="/images/skew-heap-02.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;and this is the final merge result:&lt;/p&gt;
&lt;p&gt;&lt;img alt="skew heap 03" class="img-responsive" src="/images/skew-heap-03.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The end result is actually leftist heap but there is no guaranteed that this is
always the case. If you take a look, &lt;span class="math"&gt;\(H_1\)&lt;/span&gt; is not lefist heap.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="runtime-analysis"&gt;Runtime analysis&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;deleteMin&lt;/code&gt;, and &lt;code&gt;insert&lt;/code&gt; are all running in &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; amortized time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 6&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.cmu.edu/~ckingsf/bioinfo-lectures/heaps.pdf"&gt;CMU lecture slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="heaps"></category><category term="maw"></category></entry><entry><title>Leftist heap</title><link href="https://zhu45.org/posts/2017/Apr/04/leftist-heap/" rel="alternate"></link><published>2017-04-04T10:30:00+08:00</published><updated>2017-04-04T10:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-04:/posts/2017/Apr/04/leftist-heap/</id><summary type="html">&lt;p&gt;Summary for leftist heap&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;leftist heaps&lt;/em&gt; part in MAW Chapter 6.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Merge two priority queues into one can be a very hard operation to do. For binary
heap, this can be done at &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;. However, we want to do better. Leftist heap
is a priority queue that supports merge operation in &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;The idea for leftist heap is that we want to make the tree structure imbalance
as much as possible to make merge fast. This is achieved by leftist heap property.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;null path length&lt;/em&gt; &lt;span class="math"&gt;\(Npl(X)\)&lt;/span&gt; of any node &lt;span class="math"&gt;\(X\)&lt;/span&gt; is the length of the shortest path 
from &lt;span class="math"&gt;\(X\)&lt;/span&gt; to a node without two children. Thus, the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of a node with zero or
one child is 0 and &lt;span class="math"&gt;\(Npl(NULL) = -1\)&lt;/span&gt;. In addition, the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of any node is 1 more
than the minimum of the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of its children.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;leftist heap property is that for every node &lt;span class="math"&gt;\(X\)&lt;/span&gt; in the heap, the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of the
left child is at least as large as that of the right child.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;In fact, the leftist heap property is the leftist property applies to heap.
In other words, if every node in a tree has the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of the left child
is at least as large as that of the right child, then we call this tree
a &lt;em&gt;leftist tree&lt;/em&gt;. A leftist heap is simply a leftist tree with keys in heap order.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The number in the each node below is the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of that node. By the leftist property,
only the left tree is leftist.&lt;/p&gt;
&lt;p&gt;&lt;img alt="leftist tree example" class="img-responsive" src="/images/leftist-tree-example.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;If rightmost path of leftist tree has &lt;span class="math"&gt;\(r\)&lt;/span&gt; nodes, then the whole tree has at least
&lt;span class="math"&gt;\(2^r-1\)&lt;/span&gt; nodes. &lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The above property leads to: &lt;span class="math"&gt;\(n \ge 2^r-1\)&lt;/span&gt;, so &lt;span class="math"&gt;\(r\)&lt;/span&gt; is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;. Since our 
fundamental operation &lt;code&gt;merge&lt;/code&gt; will perform all the work on the right path,
then we can have a &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; &lt;code&gt;merge&lt;/code&gt; operation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;A perfectly balanced tree forms if keys 1 to &lt;span class="math"&gt;\(2^k-1\)&lt;/span&gt; are inserted in order into an
initially empty leftist heap.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="operations"&gt;Operations&lt;/h2&gt;
&lt;h3 id="mergeh1-h2"&gt;&lt;code&gt;merge(H1, H2)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;As with &lt;a href="https://zhu45.org/posts/2017/Feb/13/splay-tree/"&gt;splay&lt;/a&gt; in splay trees, &lt;code&gt;merge&lt;/code&gt; is
the fundamental operation that is used to implement other operations in leftist 
heap(i.e., &lt;code&gt;insert&lt;/code&gt;, &lt;code&gt;deleteMin&lt;/code&gt;). &lt;/p&gt;
&lt;p&gt;The key point for the merge operation are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;recursively merge the heap with the larger root with the right subheap of the heap
with the smaller root.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We update &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of the merged root and swap left and right subtrees just below
root, if needed, to keep leftist property of merged result.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following picture shows a good example of &lt;code&gt;merge&lt;/code&gt; steps. Note that the &lt;span class="math"&gt;\(Npl\)&lt;/span&gt; of the node in
picture is 1 larger than our’s definition. The blue curve represents the final
swap step.&lt;/p&gt;
&lt;p&gt;&lt;img alt="leftist heap merge example" class="img-responsive" src="/images/leftist-heap-merge.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;Another example can be seen from MAW 6.16 in 
&lt;a href="https://zhu45.org/posts/2017/Mar/26/maw-chapter-6-priority-queues-heaps-writing-questions/"&gt;my chapter 6 writing question post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The actual implementation in C is below, which is copied from maw p.198:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;
&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Merge1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Merge1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;
&lt;span class="n"&gt;Merge1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Single node; H1-&amp;gt;Right is already NULL&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Npl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Npl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;swapChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Npl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Npl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="insert"&gt;insert&lt;/h3&gt;
&lt;p&gt;We can carry out insertion by making the item to be inserted a one-node heap
and perform a merge. &lt;/p&gt;
&lt;p&gt;Reference section offers a link to visualize the whole insertion process. The
actual implementation is on maw p.199 and copied below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;
&lt;span class="n"&gt;Insert1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Npl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SingleNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="deletemin"&gt;deleteMin&lt;/h3&gt;
&lt;p&gt;deleteMin can be done by remove the root and merge the left and subtree tree into
a new leftist heap.&lt;/p&gt;
&lt;p&gt;The actual implementation is on maw p.200 and copied below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;
&lt;span class="n"&gt;DeleteMin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PriorityQueue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LeftHeap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RightHeap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Priority queue is empty"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;LeftHeap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;RightHeap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;H&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kr"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LeftHeap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RightHeap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="buildheap"&gt;BuildHeap&lt;/h3&gt;
&lt;p&gt;As described in MAW 6.22, we can perform &lt;code&gt;BuildHeap&lt;/code&gt; in linear time for leftist 
heaps by considering each element as a one-node leftist heap, placing all these
heaps on a queue, and performing the following step: Until only one heap is on 
the queue, dequeue two heaps, merge them, and enqueue the result.&lt;/p&gt;
&lt;p&gt;This algorithm is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; in the worst time.&lt;/p&gt;
&lt;h2 id="runtime-analysis"&gt;Runtime analysis&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;deleteMin&lt;/code&gt;, and &lt;code&gt;insert&lt;/code&gt; are all running in &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 6&lt;/li&gt;
&lt;li&gt;http://www.cs.cmu.edu/~ckingsf/bioinfo-lectures/heaps.pdf&lt;/li&gt;
&lt;li&gt;https://www.cs.usfca.edu/~galles/visualization/LeftistHeap.html (good tool to visualize the operations)&lt;/li&gt;
&lt;li&gt;http://courses.cs.washington.edu/courses/cse326/08sp/lectures/05-leftist-heaps.pdf&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="heaps"></category><category term="maw"></category></entry><entry><title>Binary heap</title><link href="https://zhu45.org/posts/2017/Apr/02/binary-heap/" rel="alternate"></link><published>2017-04-02T11:30:00+08:00</published><updated>2017-04-02T11:30:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-04-02:/posts/2017/Apr/02/binary-heap/</id><summary type="html">&lt;p&gt;Binary heap summary&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;binary heap&lt;/em&gt; and its generalization &lt;em&gt;d-heap&lt;/em&gt; part in MAW Chapter 6.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;The motivation for priority queue majorly comes from the fact that not all things
are equally weighted. I’ll summarize the applications of priority queues in my
end-chapter summary post. &lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;A binary heap is a binary tree (NOT a BST) that is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Complete (structure property):&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;the tree is completely filled except possibly the bottom level, which is filled
from left to right.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;satisfies the heap order property:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For every nodex &lt;span class="math"&gt;\(X\)&lt;/span&gt;, the key in the parent of &lt;span class="math"&gt;\(X\)&lt;/span&gt; is smaller than (or equal to) the
key in &lt;span class="math"&gt;\(X\)&lt;/span&gt;, with the exception of the root (which has no parent). In other words,
every node is less than or equal to its children.&lt;/p&gt;
&lt;p&gt;This property guarantees that the root node is always the smallest node &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Here are some examples:&lt;/p&gt;
&lt;p&gt;&lt;img alt="binary heap examples" class="img-responsive" src="/images/binary-heap.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Since complete binary tree of height &lt;span class="math"&gt;\(h\)&lt;/span&gt; has between &lt;span class="math"&gt;\(2^h\)&lt;/span&gt; and &lt;span class="math"&gt;\(2^{h+1}-1\)&lt;/span&gt; nodes, 
  the height of a binary heap is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;For binary heaps, &lt;code&gt;BuildHeap&lt;/code&gt; does at most &lt;span class="math"&gt;\(2N-2\)&lt;/span&gt; comparisons between elements.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="remarks-on-implementation"&gt;Remarks on implementation&lt;/h2&gt;
&lt;p&gt;We use array as the actual implementation for the binary heap above. 
For any element in array position &lt;span class="math"&gt;\(i\)&lt;/span&gt;, the left child is in position &lt;span class="math"&gt;\(2i\)&lt;/span&gt;, the
right child is in the cell after the left child &lt;span class="math"&gt;\((2i+1)\)&lt;/span&gt;, and the parent is in position
&lt;span class="math"&gt;\(\lfloor i/2 \rfloor\)&lt;/span&gt;. Position 0 is used as a sentinel.&lt;/p&gt;
&lt;p&gt;The reason we use the array implementation is that dealing with pointers are quite
expensive to do.&lt;/p&gt;
&lt;h2 id="operations"&gt;Operations&lt;/h2&gt;
&lt;h3 id="insert"&gt;Insert&lt;/h3&gt;
&lt;p&gt;We add the value as the new node at the end of the array, which is the next avaliable
location in the tree. Then, we need to maintain the heap order property by doing 
a simple insertion sort operation on the path from the new place to the root to find
the correct place for it in the tree. This is called &lt;em&gt;percolate up&lt;/em&gt; &lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2"&gt;2&lt;/a&gt;&lt;/sup&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img alt="binary heap percolate up" class="img-responsive" src="/images/binary-heap-percolate-up.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We start at last node and keep comparing with parent &lt;span class="math"&gt;\(A[i/2]\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If parent larger, copy parent down and go up one level&lt;/li&gt;
&lt;li&gt;Done if parent &lt;span class="math"&gt;\(\le\)&lt;/span&gt; item or reached top node &lt;span class="math"&gt;\(A[1]\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="binary heap percolate up done" class="img-responsive" src="/images/binary-heap-percolate-up-done.PNG"/&gt;&lt;/p&gt;
&lt;h3 id="deletemin"&gt;DeleteMin&lt;/h3&gt;
&lt;p&gt;We delete and return the value at root node in this operation. Same as the insert, 
we need to maintain the binary heap properties. &lt;/p&gt;
&lt;p&gt;By removing the root node’s value, we have a “hole” at the root. We use the last
node’s value in the tree to fill in the hole. By doing this way, we maintain the 
structure property. Now, we need to maintain the heap order property. Similar to 
insertion, we can do a simple insertion sort-like operation to find the correct
place for it in the tree. This is called &lt;em&gt;percolate down&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="binary heap percolate down" class="img-responsive" src="/images/binary-heap-percolate-down.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep comparing with children &lt;span class="math"&gt;\(A[2i]\)&lt;/span&gt; and &lt;span class="math"&gt;\(A[2i+1]\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Copy smaller child up and go down one level&lt;/li&gt;
&lt;li&gt;Done if both children are &lt;span class="math"&gt;\(\ge\)&lt;/span&gt; item or reached a leaf node&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="other-heap-operations"&gt;Other heap operations&lt;/h3&gt;
&lt;p&gt;The following operations (with &lt;span class="math"&gt;\(P\)&lt;/span&gt; argument) require the position of every element in the heap known
by some other method in order to make them cheap to perform.&lt;/p&gt;
&lt;h4 id="decreasekeyp-delta-h"&gt;&lt;code&gt;DecreaseKey&lt;/code&gt;(P, &lt;span class="math"&gt;\(\delta\)&lt;/span&gt;, H)&lt;/h4&gt;
&lt;p&gt;decrease the key value of node at position &lt;span class="math"&gt;\(P\)&lt;/span&gt; by a positive amount &lt;span class="math"&gt;\(\delta\)&lt;/span&gt;. We 
can first subtract &lt;span class="math"&gt;\(\delta\)&lt;/span&gt; from current value at &lt;span class="math"&gt;\(P\)&lt;/span&gt;. Then we &lt;em&gt;percolate up&lt;/em&gt; to fix.
This requires &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time.&lt;/p&gt;
&lt;h4 id="increasekeyp-delta-h"&gt;&lt;code&gt;IncreaseKey&lt;/code&gt;(P, &lt;span class="math"&gt;\(\delta\)&lt;/span&gt;, H)&lt;/h4&gt;
&lt;p&gt;increase the key value of node at position &lt;span class="math"&gt;\(P\)&lt;/span&gt; by a positive amount &lt;span class="math"&gt;\(\delta\)&lt;/span&gt;. We
can add &lt;span class="math"&gt;\(\delta\)&lt;/span&gt; to current value at &lt;span class="math"&gt;\(P\)&lt;/span&gt; then &lt;em&gt;percolate down&lt;/em&gt; to fix. This requires
&lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time.&lt;/p&gt;
&lt;h4 id="deleteph"&gt;&lt;code&gt;Delete(P,H)&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;removes the node at position &lt;span class="math"&gt;\(P\)&lt;/span&gt; from the heap. We can use &lt;code&gt;DecreaseKey&lt;/code&gt;(P, &lt;span class="math"&gt;\(\infty\)&lt;/span&gt;, H)
followed by &lt;code&gt;DeleteMin&lt;/code&gt;. The running time is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h4 id="buildheaph"&gt;&lt;code&gt;Buildheap(H)&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;takes as input &lt;span class="math"&gt;\(N\)&lt;/span&gt; keys and construct a binary heap from it. This is known as Floyd’s algorithm.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Place the &lt;span class="math"&gt;\(N\)&lt;/span&gt; keys into the tree in order. This satisfies the structure property.&lt;/li&gt;
&lt;li&gt;Then we do the following to maintain the heap order property.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="c1"&gt;; i &amp;gt; 0; i--)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;PercolateDown&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This alogrithm runs in &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; time. Detailed proof see MAW p.189.&lt;/p&gt;
&lt;h4 id="mergeh1h2"&gt;&lt;code&gt;Merge(H1,H2)&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;We merge two heaps &lt;span class="math"&gt;\(H1\)&lt;/span&gt; and &lt;span class="math"&gt;\(H2\)&lt;/span&gt; of size &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;. &lt;span class="math"&gt;\(H1\)&lt;/span&gt; and &lt;span class="math"&gt;\(H2\)&lt;/span&gt; are stored in two
arrays. We can do &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; insert but this requires &lt;span class="math"&gt;\(O(N\log N)\)&lt;/span&gt; time. We can do better
by copy &lt;span class="math"&gt;\(H2\)&lt;/span&gt; at the end of &lt;span class="math"&gt;\(H1\)&lt;/span&gt; and use &lt;code&gt;BuildHeap&lt;/code&gt;. This requires &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; time &lt;sup id="fnref:3"&gt;&lt;a class="footnote-ref" href="#fn:3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id="runtime-analysis"&gt;Runtime analysis&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Space: &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; (an array of size &lt;span class="math"&gt;\(N+1\)&lt;/span&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Insert: &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DeleteMin: &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="d-heaps"&gt;d-heaps&lt;/h1&gt;
&lt;p&gt;d-heaps is the generalization of binary heap: we have &lt;span class="math"&gt;\(d\)&lt;/span&gt; children instead of 2.
Similar to B-tree, this structure will makes the heaps shallower and is useful for
heaps too big for memory. &lt;/p&gt;
&lt;p&gt;Everything is same to the binary heap except that it takes &lt;span class="math"&gt;\(d-1\)&lt;/span&gt; comparisons to find
the minimum of &lt;span class="math"&gt;\(d\)&lt;/span&gt; children (in binary heap, we do comparison once). Then, for
&lt;code&gt;DeleteMin&lt;/code&gt;, for example, takes &lt;span class="math"&gt;\(O(d\log_d N)\)&lt;/span&gt;. Other operations runtime adjusts similarly.&lt;/p&gt;
&lt;p&gt;In terms of array implementation, for entry located in position &lt;span class="math"&gt;\(i\)&lt;/span&gt;, the parent is
at &lt;span class="math"&gt;\(\lfloor{\frac{i + (d-2)}{d}}\rfloor\)&lt;/span&gt; and the children are at &lt;span class="math"&gt;\(id-(d-2), \dots, id+1\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 6&lt;/li&gt;
&lt;li&gt;Lecture slides &lt;a href="https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture4.pdf"&gt;4&lt;/a&gt;,
&lt;a href="https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture08.pdf"&gt;8&lt;/a&gt;, and 
&lt;a href="https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture11.pdf"&gt;11&lt;/a&gt; from U.Washington&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The heap order property is for min heap. If you want to have a max heap, then
the heap order property should be that every node is greater than or equal to 
its children. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Position 0 is used as a sentinel, which holds the value that is smaller than
(or equal to) any element in the heap. This is because every iteration of insert
needs to test: 1. if it has reached the top node A[1] 2. if parent &lt;span class="math"&gt;\(\le\)&lt;/span&gt; item
The first test can be avoid by using sentinel b/c it then becomes a special case
of second test. &lt;a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;As shown on MAW p.183, empirical study shows that on average, percolation terminates
early: average &lt;em&gt;insert&lt;/em&gt; moves an element up 1.607 levels. This means that 
binary heap support insertion in &lt;em&gt;constant average&lt;/em&gt; time per operation. &lt;a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="heaps"></category><category term="maw"></category></entry><entry><title>MAW Chapter 6: Priority Queues (Heaps) writing questions</title><link href="https://zhu45.org/posts/2017/Mar/26/maw-chapter-6-priority-queues-heaps-writing-questions/" rel="alternate"></link><published>2017-03-26T12:01:00+08:00</published><updated>2017-03-26T12:01:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-03-26:/posts/2017/Mar/26/maw-chapter-6-priority-queues-heaps-writing-questions/</id><summary type="html">&lt;p&gt;My solutions to selected problems in MAW Chapter 6&lt;/p&gt;</summary><content type="html">&lt;h2 id="solutions"&gt;Solutions&lt;/h2&gt;
&lt;p&gt;including: MAW 6.6, 6.7, 6.9, 6.13, 6.14, 6.16, 6.17, 6.27, 6.28,&lt;/p&gt;
&lt;h3 id="maw-66"&gt;MAW 6.6&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;How many nodes are in the large heap in Figure 6.13?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This question is interesting in the sense that the algorithm of counting reflecting
the underneath implemenation structure. Since the binary heap is actually implemented 
in terms of array, we start with &lt;span class="math"&gt;\(i = 1\)&lt;/span&gt; and position at the root. We follow the path
toward the last node, doubling &lt;span class="math"&gt;\(i\)&lt;/span&gt; when taking a left child, and doubling &lt;span class="math"&gt;\(i\)&lt;/span&gt; and adding
one when taking a right child. Then, we have the following calculation:
&lt;span class="math"&gt;\(2(2(2(2(2(2(2i+1)+1)))))+1 = 225\)&lt;/span&gt;. The picture below shows the path from the root 
to the node in the last position:&lt;/p&gt;
&lt;p&gt;&lt;img alt="MAW 6.6" class="img-responsive" src="/images/maw-6-6.PNG"/&gt;&lt;/p&gt;
&lt;h3 id="maw-67"&gt;MAW 6.7&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;b. show that a heap of eight elements can be constructed in eight comparisons between 
   heap elements.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thie question is interesting because it offers another method we can use when build a binary
heap with even number of elements. That is, we build binomial queue first. since the binary 
form of &lt;span class="math"&gt;\(8\)&lt;/span&gt; is &lt;span class="math"&gt;\(1000_2\)&lt;/span&gt;, this means we will have only one binomial tree &lt;span class="math"&gt;\(B_3\)&lt;/span&gt; inside the binomial queue.
Once we construct this binomial tree, we need one last step to tweek the binomial tree to
follow binary heap property, namely each node has to have either zero or two children.&lt;/p&gt;
&lt;p&gt;For this question, it takes seven comparisons to construct the binomial queue (with a solo binomial tree)
and we get the following:&lt;/p&gt;
&lt;p&gt;&lt;img alt="MAW 6.7.b" class="img-responsive" src="/images/maw-6-7-b.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;Then we need to restore the binary heap property because “a” node has three children.
This can be done by the eighth compariosn between “b” and “c”. If “c” is less than “b”,
then “b” is made a child of “c”. Otherwise, both “c” and “d” are made children of “b”.&lt;/p&gt;
&lt;h3 id="maw-69"&gt;MAW 6.9&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;a. Give an algorithm to find all nodes less than some value, X, in a binary heap.
   Your algorithm should run in &lt;span class="math"&gt;\(O(K)\)&lt;/span&gt;, where &lt;span class="math"&gt;\(K\)&lt;/span&gt; is the number of nodes output.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The big idea is that we perform a preorder traversal of the heap. In detail, we start
from the root of the heap. If value of the root is smaller than &lt;span class="math"&gt;\(X\)&lt;/span&gt;, then we output
this value and call procedure recursively once for its left child and once for its right 
child. If the value of a node is bigger or equal than &lt;span class="math"&gt;\(X\)&lt;/span&gt;, then the procedure halts
without printing the value. We don’t need to check the children by heap definition.&lt;/p&gt;
&lt;p&gt;The complexity of this algorithm is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; in worst case, where &lt;span class="math"&gt;\(N\)&lt;/span&gt; is the total number
of nodes in the heap. This happens when every node in the heap is smaller than &lt;span class="math"&gt;\(X\)&lt;/span&gt;, and 
the procedure has to call each node of the heap.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;b. Does your algorithm extend to any of the other heap structures dicussed in 
   this chapter?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes. It works for leftist heap, skew heap, and d-heaps.&lt;/p&gt;
&lt;h3 id="maw-613"&gt;MAW 6.13&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;If a d-heap is stored as an array, for an entry located in position &lt;span class="math"&gt;\(i\)&lt;/span&gt;,
where are the parents and children?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s begin with children. Assume that position &lt;span class="math"&gt;\(i\)&lt;/span&gt; corresponds to the &lt;span class="math"&gt;\(X\)&lt;/span&gt;th node
of level &lt;span class="math"&gt;\(l\)&lt;/span&gt;. Therefore&lt;/p&gt;
&lt;div class="math"&gt;$$
i = \sum_{j=0}^{l-1}d^j+X
$$&lt;/div&gt;
&lt;p&gt;&lt;span class="math"&gt;\(\sum_{j=0}^{l-1}d^j\)&lt;/span&gt; is a geometric series whose first term equals &lt;span class="math"&gt;\(1\)&lt;/span&gt;, whose
common ratio is &lt;span class="math"&gt;\(d\)&lt;/span&gt;, and that contains &lt;span class="math"&gt;\(l\)&lt;/span&gt; terms in total. Thus, the result is
&lt;span class="math"&gt;\(\frac{d^l-1}{d-1}\)&lt;/span&gt; and thus, we have &lt;/p&gt;
&lt;div class="math"&gt;$$
i = \frac{d^l-1}{d-1} + X
$$&lt;/div&gt;
&lt;p&gt;We now calculate the position of &lt;span class="math"&gt;\(i\)&lt;/span&gt;‘s second last child in terms of &lt;span class="math"&gt;\(d\)&lt;/span&gt;, &lt;span class="math"&gt;\(l\)&lt;/span&gt;, and
&lt;span class="math"&gt;\(X\)&lt;/span&gt;. This equals &lt;span class="math"&gt;\(i\)&lt;/span&gt;, plus the number of nodes after &lt;span class="math"&gt;\(i\)&lt;/span&gt; on level &lt;span class="math"&gt;\(l\)&lt;/span&gt;, plus &lt;span class="math"&gt;\(d\)&lt;/span&gt;
times the number of nodes before &lt;span class="math"&gt;\(i\)&lt;/span&gt; on level &lt;span class="math"&gt;\(l\)&lt;/span&gt;, plus &lt;span class="math"&gt;\(d-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
&amp;amp;=&amp;amp; \frac{d^l-1}{d-1} + X + d^l - X + (X-1)d + d - 1 \\
&amp;amp;=&amp;amp; \frac{d^l-1}{d-1} + d^l-1 + dX \\
&amp;amp;=&amp;amp; \frac{d(d^l-1)}{d-1} + dX \\
&amp;amp;=&amp;amp; d(\frac{d^l-1}{d-1} + X) \\
&amp;amp;=&amp;amp; di
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Therefore the second last child of &lt;span class="math"&gt;\(i\)&lt;/span&gt; is in position &lt;span class="math"&gt;\(id\)&lt;/span&gt;. It follows that the children
of &lt;span class="math"&gt;\(i\)&lt;/span&gt; are in positions &lt;span class="math"&gt;\(id-(d-2), \dots, id+1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;A node is a child of &lt;span class="math"&gt;\(i\)&lt;/span&gt; if and only if it is in one of the positions &lt;span class="math"&gt;\(id-(d-2), \dots, id+1\)&lt;/span&gt;.
So what you want here is a function that will map each of these to &lt;span class="math"&gt;\(i\)&lt;/span&gt;, but will not
map any other value to &lt;span class="math"&gt;\(i\)&lt;/span&gt;. Let &lt;span class="math"&gt;\(j\)&lt;/span&gt; be any of these values. Clearly,&lt;/p&gt;
&lt;div class="math"&gt;$$
\lfloor{\frac{j + (d-2)}{d}}\rfloor = i
$$&lt;/div&gt;
&lt;p&gt;But if &lt;span class="math"&gt;\(j\)&lt;/span&gt; is greater than &lt;span class="math"&gt;\(id+1\)&lt;/span&gt; or less than &lt;span class="math"&gt;\(id - (d-2)\)&lt;/span&gt; then&lt;/p&gt;
&lt;div class="math"&gt;$$
\lfloor{\frac{j + (d-2)}{d}}\rfloor \ne i
$$&lt;/div&gt;
&lt;p&gt;Thus we have our function which can now be used to work out the position of the
parent of &lt;span class="math"&gt;\(i\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="math"&gt;$$
\lfloor{\frac{i + (d-2)}{d}}\rfloor
$$&lt;/div&gt;
&lt;h2 id="maw-614"&gt;MAW 6.14&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose we need to perform &lt;span class="math"&gt;\(M\)&lt;/span&gt; &lt;code&gt;PercolateUp&lt;/code&gt; and &lt;span class="math"&gt;\(N\)&lt;/span&gt; &lt;code&gt;DeleteMiin&lt;/code&gt; on a d-heap
that initially has &lt;span class="math"&gt;\(N\)&lt;/span&gt; elements.&lt;/p&gt;
&lt;p&gt;a. What is the total running time of all operations in terms of &lt;span class="math"&gt;\(M\)&lt;/span&gt;, &lt;span class="math"&gt;\(N\)&lt;/span&gt;, and &lt;span class="math"&gt;\(d\)&lt;/span&gt;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A &lt;code&gt;percolateUp&lt;/code&gt; operation on a d-heap with &lt;span class="math"&gt;\(N\)&lt;/span&gt; elements takes &lt;span class="math"&gt;\(O(\log_d N)\)&lt;/span&gt; steps.
The key is that each time we bubble the hole up, we only do comparison once: 
compare the insertion value with the parent of the hole (Figure 6.6, 6.7 helps understanding).&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;deleteMin&lt;/code&gt; operation on a d-heap with &lt;span class="math"&gt;\(N\)&lt;/span&gt; elements takes &lt;span class="math"&gt;\(O(d \log_d N)\)&lt;/span&gt; steps.
Here, we need to feel the empty hole with the minimum value of its children. This can
take &lt;span class="math"&gt;\(d\)&lt;/span&gt; comparison to find the minimum (see p.184). &lt;/p&gt;
&lt;p&gt;Thus in total this will take &lt;span class="math"&gt;\(O(M\log_d N + Nd\log_d N)\)&lt;/span&gt; steps.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;b. If &lt;span class="math"&gt;\(d = 2\)&lt;/span&gt;, what is the running time of all heap operations?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Substitute 2 into the formula calculated in part a) gives &lt;span class="math"&gt;\(O((M+N)\log_2 N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;c. If &lt;span class="math"&gt;\(d = \theta (N)\)&lt;/span&gt;, what is the total running time?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(d = \theta (N)\)&lt;/span&gt; then &lt;span class="math"&gt;\(d = cN\)&lt;/span&gt;, where &lt;span class="math"&gt;\(c\)&lt;/span&gt; is a constant value independent of &lt;span class="math"&gt;\(N\)&lt;/span&gt;.
Substituting &lt;span class="math"&gt;\(cN\)&lt;/span&gt; into the formula calculated in part a) gives:&lt;/p&gt;
&lt;div class="math"&gt;$$ 
M\log_{cN} N + NcN \log_{cN}N = O(M + N^2)
$$&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;d. What choice of &lt;span class="math"&gt;\(d\)&lt;/span&gt; minimizes the total running time?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span class="math"&gt;\(d = max(2, M/N)\)&lt;/span&gt; (See the related discussion at the end of Section 11.4)&lt;/p&gt;
&lt;!--http://mail.csis.ul.ie/~cs4115/resources/sol10.pdf--&gt;
&lt;h2 id="maw-616"&gt;MAW 6.16&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Merge the two leftist heaps in Figure 6.58&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="MAW 6.16" class="img-responsive" src="/images/maw-6-16-problem.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;The book doesn’t do a well job on displaying the detailed steps in merging the 
leftist heap. So, I decide to use this problem as an illustration. By algorithm
description on p. 194 and the actual algorithm implementation on p.189., there are
two key points in the algorithm:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;recursively merge the heap with the larger root with the right subheap of
the heap with the smaller root.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We do the swap at the root.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The following shows the steps to get the final answer for this problem:&lt;/p&gt;
&lt;p&gt;&lt;img alt="MAW 6.16 solution" class="img-responsive" src="/images/maw-6-16-solution.jpg" style="width:700px;height:400px"/&gt;&lt;/p&gt;
&lt;h2 id="maw-617"&gt;MAW 6.17&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Show the result of inserting keys 1 to 15 in order into an initially empty leftist heap.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Use &lt;a href="https://www.cs.usfca.edu/~galles/visualization/LeftistHeap.html"&gt;this wonderful site&lt;/a&gt;
to see the whole process of insertion.&lt;/p&gt;
&lt;h2 id="maw-627"&gt;MAW 6.27&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Prove that a binomial tree &lt;span class="math"&gt;\(B_k\)&lt;/span&gt; has binomial trees &lt;span class="math"&gt;\(B_0, B_1, \dots, B_{k-1}\)&lt;/span&gt;
as children of the root.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’ll try to use two ways to prove this. Both ways are by induction but one of them
is more mathematical formula involved.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Method 1&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Clearly the claim is true for &lt;span class="math"&gt;\(k = 1\)&lt;/span&gt;. Suppose it is true for all values &lt;span class="math"&gt;\(i = 1, 2, \dots, k-1\)&lt;/span&gt;.
Since for &lt;span class="math"&gt;\(B_k\)&lt;/span&gt;, we have &lt;span class="math"&gt;\(2^k\)&lt;/span&gt; nodes. Then, by the induction hypothesis, we have
&lt;span class="math"&gt;\(2^{k-1} = 1 + 2^0 + \dots + 2^{k-2}\)&lt;/span&gt;. Now, multiplying both sides of the equation
by 2, we have &lt;span class="math"&gt;\(2^k = 2 + 2 + \dots + 2^{k-1}\)&lt;/span&gt;, which is the same as
&lt;span class="math"&gt;\(2^k = 1 + 2^0 + \dots + 2^{k-1}\)&lt;/span&gt;. This completes the proof.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Method 2&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Again the claim is true for &lt;span class="math"&gt;\(k = 1\)&lt;/span&gt;. Suppose it is true for all values &lt;span class="math"&gt;\(i = 1, 2, \dots, k-1\)&lt;/span&gt;.
A &lt;span class="math"&gt;\(B_k\)&lt;/span&gt; tree is fromed by attaching a &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt; tree to the root of a &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt; tree.
Thus, by induction, it contains a &lt;span class="math"&gt;\(B_0\)&lt;/span&gt; through &lt;span class="math"&gt;\(B_{k-2}\)&lt;/span&gt; tree, as well as the
newly attached &lt;span class="math"&gt;\(B_{k-1}\)&lt;/span&gt; tree, proving the claim.&lt;/p&gt;
&lt;h2 id="maw-628"&gt;MAW 6.28&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Prove that a binomial tree of height &lt;span class="math"&gt;\(k\)&lt;/span&gt; has &lt;span class="math"&gt;\({k \choose d}\)&lt;/span&gt; nodes at depth &lt;span class="math"&gt;\(d\)&lt;/span&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Proof is by induction. Clearly the claim is true for &lt;span class="math"&gt;\(k=1\)&lt;/span&gt;. Assume true for 
all values &lt;span class="math"&gt;\(i=1,2,\dots,k\)&lt;/span&gt;. A &lt;span class="math"&gt;\(B_{k+1}\)&lt;/span&gt; tree is formed by attaching a &lt;span class="math"&gt;\(B_k\)&lt;/span&gt; tree
to the original &lt;span class="math"&gt;\(B_k\)&lt;/span&gt; tree. The original tree has &lt;span class="math"&gt;\({k \choose d}\)&lt;/span&gt; nodes at depth
&lt;span class="math"&gt;\(d\)&lt;/span&gt; by induction hypothesis. The attached tree had &lt;span class="math"&gt;\(\binom{k}{d-1}\)&lt;/span&gt; nodes at depth
&lt;span class="math"&gt;\(d-1\)&lt;/span&gt;, which are now at depth &lt;span class="math"&gt;\(d\)&lt;/span&gt;. Adding these two terms we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\binom{k+1}{d} = \binom{k}{d} + \binom{k}{d-1}
$$&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="heaps"></category><category term="proof"></category><category term="math"></category><category term="maw"></category></entry><entry><title>Hash Table</title><link href="https://zhu45.org/posts/2017/Mar/17/hash-table/" rel="alternate"></link><published>2017-03-17T15:56:00+08:00</published><updated>2017-03-17T15:56:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-03-17:/posts/2017/Mar/17/hash-table/</id><summary type="html">&lt;p class="first last"&gt;Summary of hash table for MAW Chapter 5&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This post summarizes the basic idea about hash table. It is created based on MAW Chapter 5.&lt;/p&gt;
&lt;div class="section" id="reflection"&gt;
&lt;h2&gt;Reflection&lt;/h2&gt;
&lt;div class="section" id="motivation"&gt;
&lt;h3&gt;Motivation&lt;/h3&gt;
&lt;p&gt;In the previous chapter, we implement the dictionary (map) ADT using tree structure.
A typical find or insert operations require &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time. However, this is
not good enough compared with &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; time. This is place where hash tables implementation
can shine. Hash tables is a data structure that is designed for &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; find, insert, and delete
operations. The only downside compared hash tables with tree structure is the ill support for ordering elements.&lt;/p&gt;
&lt;img alt="chapter5 ADT picture" class="img-responsive" src="/images/maw-chap5.PNG" style="width: 700px;"/&gt;&lt;/div&gt;
&lt;div class="section" id="general-idea"&gt;
&lt;h3&gt;General Idea&lt;/h3&gt;
&lt;p&gt;A hash table is an array of some fixed size. Then we use hash function to map each key
(i.e. a key is a string with an associated value) into some number in the range &lt;tt class="docutils literal"&gt;0&lt;/tt&gt; to
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Tablesize-1&lt;/span&gt;&lt;/tt&gt; and place it in the appropriate cell.&lt;/p&gt;
&lt;img alt="hash table idea illustration" class="img-responsive" src="/images/hashtable.PNG"/&gt;
&lt;p&gt;Ideally, two distinct keys get different cells. However, this is not possible because
there are a finite number of cells and a virtually infinite supply of keys. Thus the key
concern for hash table data structure is how to distribute the keys evenly among the cells.
This issue is addressed from two ways:
1) pick a good hash function to avoid collision (i.e. two keys hash to the same value)
2) use a good strategy to redistribute keys when collision happens.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="hash-function"&gt;
&lt;h3&gt;Hash function&lt;/h3&gt;
&lt;p&gt;Hash function is a mapping from the element key (string or number) to an integer
(the hash value). The output of the hash function must always be less than the size of
array and should be as evenly distributed as possible. One thing to note here is that
the pick of hash function has high dependency on the actual content of the key set.&lt;/p&gt;
&lt;p&gt;We list some key points from the chapter here:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Choose the table size of the hash table to be the prime.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The rationale for this is that real-life data tends to have pattern, and "multiples of 61"
are probably less likely than "multiples of 60". In addition, quadratic hashing is an efficient
collision strategy to use (compared with linear hashing, double hashing) and it requires the table size
to be the prime.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;When we deal with string keys, we may use &lt;span class="math"&gt;\(\big(\sum_{i=0}^{k-1} s_i \cdot 256^i \big) \bmod TableSize\)&lt;/span&gt;
as our function.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here we use 256 because &lt;cite&gt;char&lt;/cite&gt; data is 1 byte. Other hash function may be adding up the ASCII values ofthe characters
in the string. However, this doesn't work well because if string keys are short, it will not hash evenly to all of the
hash table (see MAW p.151) and different character combinations hash to same value (i.e. "abc", "bca" all add up to the
same value).&lt;/p&gt;
&lt;p&gt;The slides listed in the reference section offer some examples on hash function pick if
we know the keys beforehand (i.e. if keys &lt;span class="math"&gt;\(s\)&lt;/span&gt; are the real numbers uniformly
distributed over &lt;span class="math"&gt;\(0 \leq s &amp;lt; 1\)&lt;/span&gt;).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="collision-strategy"&gt;
&lt;h3&gt;Collision strategy&lt;/h3&gt;
&lt;p&gt;A collision occurs when two different keys hash to the same value. By the nature of dictionary ADT,
we cannot store both data records in the same cell in the array. So, we need to come up a strategy
to resolve collision and try our best to make the keys evenly distribute among the table. There are
two main strategies discussed in the chapter: separate chaining and open addressing.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Load factor &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; defined as the ratio of the number of the elements
in the hash table to the table size. This concept appears frequently when we analyze
hash table collision resolution strategy.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="separate-chaining"&gt;
&lt;h4&gt;Separate chaining&lt;/h4&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Sometimes separate chaining is also referred as &lt;em&gt;"open hashing"&lt;/em&gt;, which means that none of the objects
are stored inside the hash table's internal array. For example, objects are stored in lists of buckets
for hash table implementng the separate chaining.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Separate chaining is to keep a list (chain or bucket) of all elements that hash to the same value. In other words,
each hash table cell holds pointer to linked list of records with same hash value.
When collision happens, we insert the hash value of the key to the corresponding linked list of
the cell that hash value should be stored. When we want to find an item, we compute the
hash value, then do find on linked list.&lt;/p&gt;
&lt;img alt="separate chaining illustration" class="img-responsive" src="/images/separate-chaining.PNG"/&gt;
&lt;p&gt;Here the worst case time happens for find operation, which can take linear time.
However, this can happen in the extreme rare case (bad luck or bad hash function).
Of course, we can build a balance tree instead of a linked list on each cell to shrink
the find time. But, the structure overhead and the compelxity of insert may make this effort not
worth it.&lt;/p&gt;
&lt;p&gt;The average length of chained list = &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;. Thus, the average time for
accessing an item = &lt;span class="math"&gt;\(O(1) + O(\lambda)\)&lt;/span&gt;. So, we want &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; to be smaller
than 1 but close to 1 if good hashing function. Thus, the general rule for
separate chaining hashing is to make the table size about as large as the number of
elements expected (let &lt;span class="math"&gt;\(\lambda \approx 1\)&lt;/span&gt;).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Actually, separate chaining doesn't restrict us to use the list to chain the objects together.
We can use a tree to organize the elements that have the same hash value.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="open-addressing"&gt;
&lt;h4&gt;Open addressing&lt;/h4&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Open addressing is sometimes referred as &lt;em&gt;"closed hashing"&lt;/em&gt;, which means that every object
is stored directly at some index in the hash table's internal array; the objects never
live outside of the internal array.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;One disadvantage for the separate chaining strategy is that we need to build linked list
for each cell, whcih introduces the overhead that can waste space. Another strategy to
resolve collision is to try other empty cells. This is called open addressing. In general,
open addressing means resolving collisions by trying a sequence of other positions in the table.
Trying the next spot is called &lt;em&gt;probing&lt;/em&gt;. More formally, cells &lt;span class="math"&gt;\(h_0(X), h_1(x), h_2(x), \dots\)&lt;/span&gt;
are tried in succession until either x is found or we find an empty location (x not present).
&lt;span class="math"&gt;\(h_i(x) = (Hash(x) + F(i)) \bmod TableSize\)&lt;/span&gt;, with &lt;span class="math"&gt;\(F(0) = 0\)&lt;/span&gt;. The function &lt;span class="math"&gt;\(F\)&lt;/span&gt;
is the collision resolution strategy.&lt;/p&gt;
&lt;p&gt;Various flavors of open addressing differ in which probe sequence they use. This is reflected in &lt;span class="math"&gt;\(F\)&lt;/span&gt;.
Three types of resolution function are discussed in the book:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Linear probing: &lt;span class="math"&gt;\(F(i) = i\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Quadratic probing: &lt;span class="math"&gt;\(F(i) = i^2\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Double hashing: &lt;span class="math"&gt;\(F(i) = i \cdot Hash_2(x)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Generally, the load factor should be below &lt;span class="math"&gt;\(\lambda = 0.5\)&lt;/span&gt; for open addressing hashing.&lt;/p&gt;
&lt;div class="section" id="linear-probing"&gt;
&lt;h5&gt;Linear probing&lt;/h5&gt;
&lt;p&gt;With linear probing, we try the cells sequentially (with wraparound) insearch of an empty cell.
This strategy has a fundamental problem called &lt;em&gt;primary clustering&lt;/em&gt;, which means blocks
of occupied cells start forming. Any key that hashes into the cluster will require several
attempts to resolve the collision, and then it will add to the cluster. In other words, primary
clustering means elements that hash to different cells probe same alternative cells.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="quadratic-probing"&gt;
&lt;h5&gt;Quadratic probing&lt;/h5&gt;
&lt;p&gt;Quadratic probing is a collision resolution method that eliminates the primary clustering problem
of linear probing. But it has its own restriction or problem:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;If quadratic probing is used and the table size is prime, then a new element
can always be inserted if the table is at least half empty. However, insertion is not guaranteed
if &lt;span class="math"&gt;\(\lambda &amp;gt; 0.5\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Secondary clustering&lt;/em&gt;, which means elements that hash to the same position will probe the same alternative cells.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="double-hashing"&gt;
&lt;h5&gt;Double hashing&lt;/h5&gt;
&lt;p&gt;Double hashing &lt;span class="math"&gt;\(F\)&lt;/span&gt; says that we apply a second hash function to x and probe
at a distance &lt;span class="math"&gt;\(hash_2(x), 2hash_2(x), \dots\)&lt;/span&gt;, and so on.&lt;/p&gt;
&lt;p&gt;When &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt; exceeds certain value, we need to build a bigger hash table of
approximately twice the size and be prime. This is called rehashing.&lt;/p&gt;
&lt;p&gt;In addition, when hash table cannot be contained in the memory and have to store part of structure on the disk,
then the disk I/O becomes the main cost. In this case, we use different hash scheme, which is called extendible hashing.
Like B-tree, this structure is widely applied in the database field.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="reference"&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;MAW Chapter 5&lt;/li&gt;
&lt;li&gt;Washington lecture slides: &lt;a class="reference external" href="https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture10.pdf"&gt;CSE 332 Lecture 10&lt;/a&gt;,
&lt;a class="reference external" href="https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture16.pdf"&gt;CSE 373 Lecture 16&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://stackoverflow.com/questions/9124331/meaning-of-open-hashing-and-closed-hashing"&gt;SO: Meaning of Open hashing and Closed hashing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"></category><category term="maw"></category><category term="hashing"></category><category term="data structures"></category></entry><entry><title>MAW Chapter 5: Hashing writing questions</title><link href="https://zhu45.org/posts/2017/Mar/16/maw-chapter-5-hashing-writing-questions/" rel="alternate"></link><published>2017-03-16T17:41:00+08:00</published><updated>2017-03-16T17:41:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-03-16:/posts/2017/Mar/16/maw-chapter-5-hashing-writing-questions/</id><summary type="html">&lt;p&gt;My solutions to selected problems in MAW Chapter 5&lt;/p&gt;</summary><content type="html">&lt;h2 id="solutions"&gt;Solutions&lt;/h2&gt;
&lt;p&gt;including: MAW 5.4, 5.5, 5.6, 5.10, 5.11&lt;/p&gt;
&lt;h3 id="maw-54"&gt;MAW 5.4&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A large number of deletions in a separate chaining hash table can cause the 
table to be fairly empty, which wastes space. In this case, we can rehash to 
a table half as large. Assume that we rehash to a larger table when there are 
twice as many elements as the table size. How empty should the table be before
we rehash to a smaller table?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We must be careful not to rehash too often. Let &lt;span class="math"&gt;\(p\)&lt;/span&gt; be the threshold (fraction of table
size) at which we rehash to a smaller table. Then, if the new table has size &lt;span class="math"&gt;\(N\)&lt;/span&gt;, 
it contains &lt;span class="math"&gt;\(2Np\)&lt;/span&gt; elements. This table will require rehashing after either 
&lt;span class="math"&gt;\(2N-2Np\)&lt;/span&gt; insertions or &lt;span class="math"&gt;\(pN\)&lt;/span&gt; deletions. Then, we don’t want to do rehashing either 
after a few insertion or a few deletions. A good strategy is to set &lt;span class="math"&gt;\(2N-2Np\)&lt;/span&gt; equals to &lt;span class="math"&gt;\(pN\)&lt;/span&gt;
and we get &lt;span class="math"&gt;\(p = \frac{2}{3}\)&lt;/span&gt;. For instance, suppose we have a table of size 300.
If we rehash at 200 elements, then the new table size is &lt;span class="math"&gt;\(N = 150\)&lt;/span&gt;, and we can do 
either 100 insertions or 100 deletions until a new rehash is required. &lt;/p&gt;
&lt;p&gt;If we know that insertions are more frequent than deletions, then we might choose &lt;span class="math"&gt;\(p\)&lt;/span&gt;
to be somewhat larger. All in all, we play around the relation between &lt;span class="math"&gt;\(2N-2Np\)&lt;/span&gt; and 
&lt;span class="math"&gt;\(pN\)&lt;/span&gt; depends on which operation we favorite.&lt;/p&gt;
&lt;h3 id="maw-55"&gt;MAW 5.5&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;An alternative collision resolution strategy is to define a sequence, &lt;span class="math"&gt;\(F(i) = r_i\)&lt;/span&gt;,
where &lt;span class="math"&gt;\(r_0 = 0\)&lt;/span&gt; and &lt;span class="math"&gt;\(r_1, r_2, \dots, r_N\)&lt;/span&gt; is a random permutation of the first &lt;span class="math"&gt;\(N\)&lt;/span&gt;
integers (each integer appears exactly once).&lt;/p&gt;
&lt;p&gt;a. Prove that under this strategy, if the table is not full, then the collision can 
always be resolved.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since the sequence &lt;span class="math"&gt;\(F(i)\)&lt;/span&gt; is defined as a random permutation of the first &lt;span class="math"&gt;\(N\)&lt;/span&gt; integers,
then each cells of the table will be probed eventually. If the table is not full, then the 
collision can always be resolved.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;b. Would this strategy be expected to eliminate clustering?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This seems to eliminate primary clustering but not secondary clustering because
all elements that hash to some location will try the same collision resolution sequence.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;c. If the load factor of the table is &lt;span class="math"&gt;\(\lambda\)&lt;/span&gt;, what is the expected time to perform
an insert and for a successful search?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The running time is probably similar to quadratic probing. The advantage here is that 
the insertion can’t fail unless the table is full.&lt;/p&gt;
&lt;h3 id="maw-56"&gt;MAW 5.6&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;What are the advantages and disadvantages of the various collision resolution strategies?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Separate chaining hashing requires the use of pointers, which costs some memory, and the 
standard method of implementing calls on memory allocation routines, which typically are
expensive. &lt;/p&gt;
&lt;p&gt;Linear probing is easily implemented, but performance degrades severly as the load 
factor increases because of primary clustering. &lt;/p&gt;
&lt;p&gt;Quadratic probing is only slightly more 
difficult to implement and gives good performance in practice. An insertion can fail 
if the table is half empty, but this is not likely. Even if it were, such an insertion 
would be so expensive that it wouldn’t matter and would almost certainly point up a 
weakness in the hash function. &lt;/p&gt;
&lt;p&gt;Double hashing eliminates primary and secondary clustering but the computation of a second
hash function can be costly. &lt;/p&gt;
&lt;h3 id="maw-510"&gt;MAW 5.10&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Describe a procedure that avoids initializing a hash table (at the expense of memory).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To each hash table slot, we can add an extra field that we’ll call &lt;code&gt;WhereOnStack&lt;/code&gt;, and 
we can keep an extra stack. When an insertion is first performed into a slot, we push
the address (or number) of the slot onto the stack and set the &lt;code&gt;WhereOnStack&lt;/code&gt; field to point
to the top of the stack. When we access a hash table slot, we check that &lt;code&gt;WhereOnStack&lt;/code&gt;
points to a valid part of the stack and that the entry in the (middle of the) stack that is 
pointed to by the &lt;code&gt;WhereOnStack&lt;/code&gt; field has that hash table slot as an address.&lt;/p&gt;
&lt;h3 id="maw-511"&gt;MAW 5.11&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose we want to find the first occurrence of a string &lt;span class="math"&gt;\(P_1P_2\dots P_k\)&lt;/span&gt; in a long 
input string &lt;span class="math"&gt;\(A_1A_2\dots A_N\)&lt;/span&gt;. We can solve this problem by hashing the pattern string,
Obtaining a hash value &lt;span class="math"&gt;\(H_p\)&lt;/span&gt;, and comparing this value with the hash value formed from 
&lt;span class="math"&gt;\(A_1A_2\dots A_k\)&lt;/span&gt;, &lt;span class="math"&gt;\(A_2A_3\dots A_{k+1}\)&lt;/span&gt;, &lt;span class="math"&gt;\(A_3A_4\dots A_{k+2}\)&lt;/span&gt;, and so on until 
&lt;span class="math"&gt;\(A_{N-k+1}A_{N-k+2}\dots A_N\)&lt;/span&gt;. If we have a match of hash values, we compare the string character
by character to verify the match. We return the position (in A) if the strings actually 
do match, and we continue in the unlikely event that the match is false.&lt;/p&gt;
&lt;p&gt;a. Show that if the hash value of &lt;span class="math"&gt;\(A_iA_{i+1}\dots A_{i+k-1}\)&lt;/span&gt; is known, then the hash 
value of &lt;span class="math"&gt;\(A_{i+1}A_{i+2}\dots A_{i+k}\)&lt;/span&gt; can be computed in constant time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As suggested by MAW p.151, we use &lt;span class="math"&gt;\(\sum_{i=0}^{KeySize-1} Key[KeySize-i-1]\cdot 32^i\)&lt;/span&gt;
as the function to compute the hash value of a given string. Then, by this definition,
&lt;span class="math"&gt;\(A_iA_{i+1}\dots A_{i+k-1}\)&lt;/span&gt; can be computed as &lt;/p&gt;
&lt;div class="math"&gt;$$
H_1 = (32^0A_i + 32^1A_{i+1} + \dots + 32^{k-1}A_{i+k-1}) \bmod N
$$&lt;/div&gt;
&lt;p&gt;similarly, &lt;span class="math"&gt;\(A_{i+1}A_{i+2}\dots A_{i+k}\)&lt;/span&gt; can be computed as &lt;/p&gt;
&lt;div class="math"&gt;$$
H_2 = (32^1A_{i+1} + \dots + 32^kA_{i+k}) \bmod N
$$&lt;/div&gt;
&lt;p&gt;If we take a look at the relationship between these two equations, we can see &lt;/p&gt;
&lt;div class="math"&gt;$$
H_2 = H_1 - 32^0A_i \bmod N + 32^kA_{i+k} \bmod N
$$&lt;/div&gt;
&lt;p&gt;This can be computed in constant time if &lt;span class="math"&gt;\(H_1\)&lt;/span&gt; is known.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;b. Show that the running time is &lt;span class="math"&gt;\(O(k+N)\)&lt;/span&gt; plus the time spent refuting false matches.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The pattern’s hash value &lt;span class="math"&gt;\(H_p\)&lt;/span&gt; computed in &lt;span class="math"&gt;\(O(K)\)&lt;/span&gt; time. Then, &lt;span class="math"&gt;\(A_1A_2\dots A_k\)&lt;/span&gt;
is computed in &lt;span class="math"&gt;\(O(K)\)&lt;/span&gt; time. Then starting with &lt;span class="math"&gt;\(A_2A_3\dots A_{k+1}\)&lt;/span&gt; and until
&lt;span class="math"&gt;\(A_{N-k+1}A_{N-k+2}\dots A_N\)&lt;/span&gt;, each hash value is computed in &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; by a) above.
Since, there are &lt;span class="math"&gt;\(N-k+1-2+1\)&lt;/span&gt; terms of &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt;, then the total running time is
&lt;span class="math"&gt;\(O(K) + O(K) + O(N-K) = O(N+K)\)&lt;/span&gt;. Of course, there is also time we spend on refuting false
matches.&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="hashing"></category><category term="proof"></category><category term="math"></category><category term="maw"></category><category term="data structures"></category></entry><entry><title>MAW: Chapter 4 Reflection</title><link href="https://zhu45.org/posts/2017/Mar/12/maw-chapter-4-reflection/" rel="alternate"></link><published>2017-03-12T10:45:00+08:00</published><updated>2017-03-12T10:45:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-03-12:/posts/2017/Mar/12/maw-chapter-4-reflection/</id><summary type="html">&lt;p class="first last"&gt;An overview summary of MAW Chapter 4&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="reflection"&gt;
&lt;h2&gt;Reflection&lt;/h2&gt;
&lt;p&gt;In Chapter 4, we learn about the tree data structure. If we take a look from ADT
perspective, the ADT we learn about is called Dictionary (a.k.a Map) ADT, which
represented by a set of (key, value) pairs that support insert, find, delete operations.
The core idea for this ADT, as you can imagine, is to store information according to
some key and be able to retrieve it efficiently. Now our big picture becomes:&lt;/p&gt;
&lt;img alt="predecessor-successor" class="img-responsive" src="/images/maw-chap4.PNG" style="width: 700px;"/&gt;&lt;p&gt;Implementing dictionary ADT with tree structure brings following advantages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Trees reflect structural relationships in the data&lt;/li&gt;
&lt;li&gt;Trees are used to represent hierarchies&lt;/li&gt;
&lt;li&gt;Trees provide an efficient insertion and searching&lt;/li&gt;
&lt;li&gt;Trees are very flexible data, allowing to move subtrees around with minumum effort&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many different tree structures get presented in this chapter. Most fundamental ones are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://zhu45.org/posts/2017/Jan/29/binary-tree-binary-search-tree/"&gt;Binary Search Tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://zhu45.org/posts/2017/Feb/05/avl-tree/"&gt;AVL tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://zhu45.org/posts/2017/Feb/13/splay-tree/"&gt;Splay tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://zhu45.org/posts/2017/Mar/11/b-tree/"&gt;B-tree&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some variations to the above structures are Order Statistic Tree (MAW 4.44), Threaded Tree (MAW 4.45),
k-d Tree (MAW 4.46), and B*-tree (MAW 4.38).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="left-out"&gt;
&lt;h2&gt;Left Out&lt;/h2&gt;
&lt;p&gt;Some material I left out when I work through this chapter:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;4.11 (cursor implementation of trees is not top priority)&lt;/li&gt;
&lt;li&gt;4.33, 4.34 (Form a nice tree drawing project; don't have time to do them now)&lt;/li&gt;
&lt;li&gt;4.12, 4.13, 4.14, 4.26.b, 4.37.b;c, 4.38 (interesting but may require too much effort)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="reference"&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture6.pdf"&gt;https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture6.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="misc"></category><category term="maw"></category></entry><entry><title>B-Tree</title><link href="https://zhu45.org/posts/2017/Mar/11/b-tree/" rel="alternate"></link><published>2017-03-11T21:32:00+08:00</published><updated>2017-03-11T21:32:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-03-11:/posts/2017/Mar/11/b-tree/</id><summary type="html">&lt;p&gt;B-tree summary&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;B tree&lt;/em&gt; part in MAW Chapter 4.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;So far we have assumed that an entire data structure can be stored in the main memory. 
However, this is not true in reality because if we have more data than can fit in main 
memory, we have to store data structure on disk. In this case, number of disk 
accesses will dominate the running time because they are very expensive comparing with the 
processor speed. Then, when we design a data structure, we have to try our best to minimize
the number of disk accesses. Under the context of tree structure, B-tree is a structure
that tries to read as much information as possible in every disk access operation.&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;B-tree is by far the most chaoatic defined structure in the sense that different people
have slightly different definitions. I’ll follow MAW’s definition and points out how MAW’s definition
is different from the other commonly seen definition.&lt;/p&gt;
&lt;p&gt;A B-tree of order &lt;span class="math"&gt;\(M\)&lt;/span&gt; is a tree with the following structural properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The leaves contain all the actual data, which are either the key temselves or pointers to records containing the keys.&lt;/li&gt;
&lt;li&gt;The root is either a leaf (when tree has &lt;span class="math"&gt;\(\le L\)&lt;/span&gt; items) or has between &lt;span class="math"&gt;\(2\)&lt;/span&gt; and &lt;span class="math"&gt;\(M\)&lt;/span&gt; children.&lt;/li&gt;
&lt;li&gt;All nonleaf nodes (except the root) have between &lt;span class="math"&gt;\(\lceil{M/2}\rceil\)&lt;/span&gt; and &lt;span class="math"&gt;\(M\)&lt;/span&gt; children (at least half full).&lt;/li&gt;
&lt;li&gt;All leaves are the same depth and have between &lt;span class="math"&gt;\(\lceil{L/2}\rceil\)&lt;/span&gt; and &lt;span class="math"&gt;\(L\)&lt;/span&gt; sorted data items, for some L (at least half full).&lt;/li&gt;
&lt;li&gt;The nonleaf nodes have room for up to &lt;span class="math"&gt;\(M-1\)&lt;/span&gt; keys to guide the searching; key &lt;span class="math"&gt;\(i\)&lt;/span&gt; represents the smallest key in subtree &lt;span class="math"&gt;\(i+1\)&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="b-tree-order-property" class="img-responsive" src="/images/b-tree-order-property.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;In MAW, the definition of B-tree is essentially known as &lt;span class="math"&gt;\(B^+-\)&lt;/span&gt;tree. Technically, the real B-tree has the key property that 
the actual data to be stored in both leaves and internal nodes, which is not the case in our definition. In some &lt;span class="math"&gt;\(B^+-\)&lt;/span&gt;tree definition,
the leaves are connected as a linked list so that we don’t have to restart the search from the root once we already traverse down to the 
leaf if we want a record that is on a leaf really close to the leaf we currently at. &lt;/p&gt;
&lt;h2 id="examples"&gt;Examples&lt;/h2&gt;
&lt;p&gt;Some typical examples in B-tree are of order 4 (known as 2-3-4 tree) and 3 (known as 2-3 tree).&lt;/p&gt;
&lt;p&gt;&lt;img alt="2-3-tree" class="img-responsive" src="/images/2-3-tree.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;B-tree is a structure that is widely used in the database system. The following picture shows a more real B-tree example. 
Suppose we have a large customer table with gigabytes of data and an index is created on the phone number column of the 
customer table to speed up search. Phone numbers stored in sorted order with information (page and slot) on where the rest of 
the customer information can be found in the customer table.&lt;/p&gt;
&lt;p&gt;&lt;img alt="real-b-tree" class="img-responsive" src="/images/real-b-tree.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;In this example, once we continue down the tree and locate the phone number we are searching for, we use the RID to fetch the rest of the customer record from the table. In this case, we use 4 page accesses to get the full customer
record from the table.&lt;/p&gt;
&lt;h2 id="operations"&gt;Operations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Find:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For find, we basically do binary search on each node to decide what subtree we should go to search. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Insertion:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The major unique manipulation is we may need to split the node at the leaves and recursives make the new parent nodes (by pushing a key up to its parent)
to the root. Other strategies regarding nodes overloaded also exist but this one is classic textbook.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deletion:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have to say deletion is the most messy one and people may always want to talk about it conceptually instead of getting hands dirty
to actually implement one. Stanford paper listed in the reference section do a concrete implementation but the route they use is to implement
a real-life B-tree deletion which may be complicated for the learner. &lt;/p&gt;
&lt;p&gt;The strategy we use for deletion is that we want to find the key to be deleted and remove it first. Then, if the leaf underflows, we borrow from 
a neighbor. If leaf underflows and can’t borrow, we merge nodes and delete parent.&lt;/p&gt;
&lt;h2 id="runtime-analysis"&gt;Runtime analysis&lt;/h2&gt;
&lt;p&gt;We first show that height &lt;span class="math"&gt;\(H\)&lt;/span&gt; is logarithmic in number of data items &lt;span class="math"&gt;\(N\)&lt;/span&gt;. Let &lt;span class="math"&gt;\(M \ge 2\)&lt;/span&gt;. Because all nodes are at least half full (except root may have
only 2 children) and all leaves are at the same level, the minimum number of data items &lt;span class="math"&gt;\(N\)&lt;/span&gt; for a height &lt;span class="math"&gt;\(H\)&lt;/span&gt; tree is &lt;/p&gt;
&lt;div class="math"&gt;$$
N \ge \underbrace{2(\lceil{M/2}\rceil)^{H-1}}_\textrm{min number of leaves}\times\underbrace{\lceil{L/2}\rceil}_\textrm{min data per leaf}
$$&lt;/div&gt;
&lt;p&gt;Then for a B-tree of order &lt;span class="math"&gt;\(M\)&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each internal node has up to &lt;span class="math"&gt;\(M-1\)&lt;/span&gt; keys to search&lt;/li&gt;
&lt;li&gt;Each internal node has between &lt;span class="math"&gt;\(\lceil{M/2}\rceil\)&lt;/span&gt; and &lt;span class="math"&gt;\(M\)&lt;/span&gt; children&lt;/li&gt;
&lt;li&gt;Depth of B-tree storing &lt;span class="math"&gt;\(N\)&lt;/span&gt; items is &lt;span class="math"&gt;\(O(\log_{\lceil{M/2}\rceil}N)\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Find then takes &lt;span class="math"&gt;\(O(\log M)\)&lt;/span&gt; to do binary search on each node to determine which branch to take. Then the total time is 
&lt;span class="math"&gt;\(O(depth \times \log M)\)&lt;/span&gt; = &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; because &lt;span class="math"&gt;\(M\)&lt;/span&gt; is small compared to &lt;span class="math"&gt;\(N\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Insertion and deletion doesn’t different from &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; because the unique manipulation takes constant amount of work and the number 
of times this unique manipulation is proportional to the height of tree.&lt;/p&gt;
&lt;h2 id="pros-cons-of-data-structure"&gt;Pros &amp;amp; Cons of data structure&lt;/h2&gt;
&lt;p&gt;What makes B-trees so disk friendly?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Many keys stored in one node &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All brought into memory in one disk access&lt;/li&gt;
&lt;li&gt;Pick &lt;span class="math"&gt;\(M\)&lt;/span&gt; wisely. See MAW’s Java version (3rd edition) p.149 for an example.&lt;/li&gt;
&lt;li&gt;Makes the binary searhc over &lt;span class="math"&gt;\(M-1\)&lt;/span&gt; keys totally worth it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Internal nodes contain only keys&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All find wants only one data item. So only bring one leaf of data items into memory.&lt;/li&gt;
&lt;li&gt;Data-item size doesn’t affect what &lt;span class="math"&gt;\(M\)&lt;/span&gt; is. We determine &lt;span class="math"&gt;\(M\)&lt;/span&gt; only by how many keys can be packed into a disk block (node).
  Thus, the key size, the children pointer size, and the block size are the only factors here.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="links-to-resources"&gt;Links to resources&lt;/h2&gt;
&lt;p&gt;Here are some of the resources I found helpful while preparing this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 4&lt;/li&gt;
&lt;li&gt;Lecture slides &lt;a href="https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture15.pdf"&gt;15&lt;/a&gt;,
&lt;a href="https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture8.pdf"&gt;8&lt;/a&gt;, and 
&lt;a href="https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture9.pdf"&gt;9&lt;/a&gt;
from U.Washington&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cs.yale.edu/homes/aspnes/pinewiki/BTrees.html"&gt;Yale pinewiki on B-tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ilpubs.stanford.edu:8090/85/1/1995-19.pdf"&gt;Stanford B-tree implementation paper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="trees"></category><category term="maw"></category></entry><entry><title>Splay Tree</title><link href="https://zhu45.org/posts/2017/Feb/13/splay-tree/" rel="alternate"></link><published>2017-02-13T01:12:00+08:00</published><updated>2017-02-13T01:12:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-02-13:/posts/2017/Feb/13/splay-tree/</id><summary type="html">&lt;p&gt;Splay tree summary&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;Splay tree&lt;/em&gt; part in MAW Chapter 4.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Ordinary BST has no balance conditions and thus, it is possible for a whole sequnece of &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; accesses to take place. This cumulative running time 
then becomes noticeable. So, we introduce the balance condition on BST to improve our running time. One way to do so is to enforce a balance condition
when nodes change (i.e. insert or delete) like AVL. However, this data structure is hard to code and rebalancing costs time. In addition, sometimes it is 
OK for us to have &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; operation as long as it occurs infrequently. In other words, A search data structure with &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; worst-case time, but a &lt;em&gt;guarantee&lt;/em&gt;
of at most &lt;span class="math"&gt;\(O(M \log N)\)&lt;/span&gt; for any &lt;span class="math"&gt;\(M\)&lt;/span&gt; consecutive operations, is good enough. Splay tree meets our needs. It is a data structure that 
lies right in-between BST (no balance condition) and AVL (very strict balance condition).&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;A splay tree is a type of balanced binary search tree. Structurally, it is identical to an ordinary binary search tree; the only difference is in the 
algorithms for finding, inserting, and deleting entries. Specifically, splay tree is a self-adjusting tree, which the structure get organized over time
as nodes are accessed (i.e., insert, delete, or find). This makes sense because if we don’t re-structure the tree each time we access an node, then 
the amortized time bound should be &lt;span class="math"&gt;\(O(M N)\)&lt;/span&gt; for a sequence of &lt;span class="math"&gt;\(M\)&lt;/span&gt; accesses instead of &lt;span class="math"&gt;\(O(M \log N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The way we restructure the tree is called &lt;em&gt;splaying&lt;/em&gt;. Chapter 4 talks about bottom-up splaying algorithms. Every time a node is accessed in a splay tree,
it is moved to the root of the tree. The amortized cost of the operation is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;. As shown by MAW, simply moving the element to the root by
rotating it up the trees does not have this property. However, the following three structuring rules do guarantee this amortized bound.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;                             y             x
   Zig (terminal case):     /     ====&amp;gt;     \               (same as AVL single rotation)
                           x                 y

                    z              z
                   /              /             x
   Zig-zag:       y     ====&amp;gt;    x   ====&amp;gt;     / \          (same as AVL double rotation)
                   \            /             y   z
                    x          y

                    z                         x
                   /            y              \
   Zig-zig:       y     ====&amp;gt;  / \   ====&amp;gt;      y
                 /            x   z              \
                x                                 z
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above pictures, x is the node that was accessed (that will
eventually be at the root of the tree).  By looking at the local
structure of the tree defined by x, x’s parent, and x’s grandparent we
decide which of three rules to follow.  We continue to
apply the rules until x is at the root of the tree.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Splay(1)

              7                    7                   7               1
             /                    /                   /                 \
            6                    6                   6                   6
           /                    /                   /                   / \
          5                    5                   1                   4   7 
         /      =======&amp;gt;      /        =======&amp;gt;     \    ======&amp;gt;      / \
        4                    4                       4               2   5
       /                    /                       / \               \
      3                    1                       2   5               3
     /                      \                       \
    2                        2                       3
   /                          \
  1                            3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="implementation-details"&gt;Implementation details&lt;/h2&gt;
&lt;p&gt;Splay tree is really a flexible data structure in the sense that there are many options to implement 
the “splay” rules and corresponding tree operations and still have the property hold. Reference &lt;a href="https://en.wikipedia.org/wiki/Splay_tree"&gt;wiki&lt;/a&gt;
for complete summary. Here, I only mention some of my findings. Please note that depends on how you implement your operations, the resulting tree
may be different (i.e. different insert algorithm may result in different tree structure but there root will be the same).&lt;/p&gt;
&lt;h3 id="insertion-bottom-up"&gt;Insertion (bottom-up)&lt;/h3&gt;
&lt;p&gt;There are two ways to do this. The first way is to use “split” to split the tree based upon the insertion value. By the property of splaying, 
we will either have the insertion value (already inside the tree) or the parent of the insertion point at the root. Then we can make our insertion 
value as the new root and adjust the orginal tree to form the new tree. For example,  if the insertion value &lt;code&gt;elem&lt;/code&gt; smaller than the root, we do&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;newT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;newT&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// we can do this b/c the result of splaying is the parent node of where we should insert.&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code is straightforward but &lt;code&gt;newT-&amp;gt;Left = T-&amp;gt;Left&lt;/code&gt; is worth a remark. Here, when &lt;code&gt;T&lt;/code&gt; is the parent of the insertion point, 
we know &lt;code&gt;T&lt;/code&gt;‘s left subtree’s values are smaller than &lt;code&gt;elem&lt;/code&gt; as well. This is because 
if there is any node &lt;span class="math"&gt;\(x\)&lt;/span&gt; greater than &lt;code&gt;elem&lt;/code&gt; but smaller than &lt;code&gt;T&lt;/code&gt;‘s value, then &lt;code&gt;T&lt;/code&gt; should be &lt;span class="math"&gt;\(x\)&lt;/span&gt; instead (by splaying), which is a contradiction.&lt;/p&gt;
&lt;p&gt;The second way is to do BST insertion first and then splay the insertion value, which is really straightforward and easy to code. &lt;/p&gt;
&lt;h2 id="deletion-bottom-up"&gt;Deletion (bottom-up)&lt;/h2&gt;
&lt;p&gt;Correspondingly there are two methods to deletion as well. The first way is to splay the to-be-deleted node. This puts the node at the root. If it is
deleted, we get two subtrees &lt;span class="math"&gt;\(T_L\)&lt;/span&gt; and &lt;span class="math"&gt;\(T_R\)&lt;/span&gt;. If we find the largest element in &lt;span class="math"&gt;\(T_L\)&lt;/span&gt;, then this element is rotated to the root of &lt;span class="math"&gt;\(T_L\)&lt;/span&gt;, and 
&lt;span class="math"&gt;\(T_L\)&lt;/span&gt; will now have a root with no right child. We can finish the deletion by making &lt;span class="math"&gt;\(T_R\)&lt;/span&gt; the right child.&lt;/p&gt;
&lt;p&gt;The second way is to do BST deletion first, and then splay the parent of the deletion point to the root. It is quite similar to BST deletion and see
the implementation &lt;a href="https://github.com/xxks-kkk/algo/blob/master/trees/splay/splay.c"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;any &lt;span class="math"&gt;\(M\)&lt;/span&gt; consecutive tree operations starting from an empty tree take at most &lt;span class="math"&gt;\(O(M \log N)\)&lt;/span&gt; time.&lt;/li&gt;
&lt;li&gt;Even though the worst-case running time is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; for operation, the amortized cost of the operation is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;if all nodes in a splay tree are accessed in sequential order, the resulting tree consists of a chain of left children. (MAW 4.26.a)&lt;/li&gt;
&lt;li&gt;if all nodes in a splay tree are accessed in sequential order, then the total access time is &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;, regardless of the initial tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pros-cons-of-data-structure"&gt;Pros &amp;amp; Cons of data structure&lt;/h2&gt;
&lt;p&gt;Splay tree is simpler and easier to program. Because of its implicity, splay tree insertion and deletion is typically faster in practice.
Find operation can be faster or slower, depending on circumstances. Splay trees are designed to give especially fast access to nodes that 
have been accessed recently, so they really excel in applications where a small fraction of the nodes are the targets of most of the find operation.&lt;/p&gt;
&lt;h2 id="todo"&gt;Todo&lt;/h2&gt;
&lt;p&gt;This post does not cover every part of the splay tree. This post will be updated once I complete the following two parts study:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 11 gives a thorough study of the amortized cost of the splay tree operations &lt;span class="math"&gt;\(O( \log N)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;MAW Chapter 12 gives implementation details on top-down splay tree.  &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;http://www.cs.cmu.edu/afs/cs/academic/class/15859-f05/www/documents/splay-trees.txt&lt;/li&gt;
&lt;li&gt;http://web.stanford.edu/class/archive/cs/cs166/cs166.1146/lectures/08/Small08.pdf (proof of properties in a concise structure)&lt;/li&gt;
&lt;li&gt;http://digital.cs.usu.edu/~allan/DS/Notes/Ch22.pdf&lt;/li&gt;
&lt;li&gt;https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture14.pdf&lt;/li&gt;
&lt;li&gt;https://people.eecs.berkeley.edu/~jrs/61b/lec/36&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="trees"></category><category term="maw"></category></entry><entry><title>AVL Tree</title><link href="https://zhu45.org/posts/2017/Feb/05/avl-tree/" rel="alternate"></link><published>2017-02-05T10:43:00+08:00</published><updated>2017-02-05T10:43:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-02-05:/posts/2017/Feb/05/avl-tree/</id><summary type="html">&lt;p&gt;AVL tree summary&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;AVL tree&lt;/em&gt; part in MAW Chapter 4.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;All BST operations are &lt;span class="math"&gt;\(O(H)\)&lt;/span&gt; time, where &lt;span class="math"&gt;\(H\)&lt;/span&gt; is the height of the tree. In the worst case
scenario, when the tree is degenerated, &lt;span class="math"&gt;\(H = N\)&lt;/span&gt;, where &lt;span class="math"&gt;\(N\)&lt;/span&gt; is the number of nodes.
Thus, the problem with BST is that it can get unbalanced and lead to the worst running time.
AVL tree is one of algorithms for keeping BST balanced (others including red-black trees, splay trees, B-trees).
Its approach to balancing tree is that we want a pretty good balance (allow a little out of balance).&lt;/p&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;p&gt;AVL tree is a &lt;em&gt;guaranteed&lt;/em&gt; &lt;span class="math"&gt;\(O(log N)\)&lt;/span&gt; binary search tree. It is identical to a BST, except 
that for every node in the tree, the height of the left and right subtrees can differ by at most 1.
(The height of an empty tree is defined to be -1).&lt;/p&gt;
&lt;p&gt;&lt;img alt="AVL-tree-concept" class="img-responsive" src="/images/AVL.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;For simplicity, we really omit the actual data part of the node. The following picture demonstrate
what AVL tree should really look like:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AVL-tree-real" class="img-responsive" src="/images/AVL-real.PNG" style="height: 300px; width: 700px;"/&gt;&lt;/p&gt;
&lt;h2 id="insertion"&gt;Insertion&lt;/h2&gt;
&lt;p&gt;AVL tree insertion is based upon BST insertion with two addition treatments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update the height information of the nodes on the path from the root to the insertion point.&lt;/li&gt;
&lt;li&gt;Restores the AVL property when find the node that violates it on the road through &lt;em&gt;rotation&lt;/em&gt; operations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are four cases inside the insertion (see MAW p.111) and we handle “outside” cases (i.e. left-left or right-right)
and “inside” cases (i.e. left-right or right-left) using single rotation and double rotation respectively.&lt;/p&gt;
&lt;p&gt;To remember single rotation, you can pick a case, say left-left and remember its picture. (right-right is a mirror case)&lt;/p&gt;
&lt;p&gt;&lt;img alt="AVL-single-rotation-left" class="img-responsive" src="https://zhu45.org/images/AVL-single-rotation-left.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;In the picture, we need to rebalance the tree at &lt;span class="math"&gt;\(k_2\)&lt;/span&gt;. This picture shows how we can implement &lt;code&gt;singleRotateWithLeft&lt;/code&gt; routine as well.
(Here, “left” means the inbalance is caused by the insertion into the left subtree of the inbalance node.)&lt;/p&gt;
&lt;p&gt;Similarly, to remember double rotation, we pick a case, say right-left and remember its picture. (left-right is a mirror case)&lt;/p&gt;
&lt;p&gt;&lt;img alt="AVL-double-rotation-right" class="img-responsive" src="https://zhu45.org/images/AVL-double-rotation-right.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;In the picture, we need to rebalance the tree at &lt;span class="math"&gt;\(k_3\)&lt;/span&gt;. The picture shows how we can implement &lt;code&gt;doubleRotateWithRight&lt;/code&gt; routine as well.
As you can see from the picture, “double rotation” is essentially the same as two “single rotation”: rotate &lt;span class="math"&gt;\(k_2\)&lt;/span&gt; and &lt;span class="math"&gt;\(k_1\)&lt;/span&gt;, then &lt;span class="math"&gt;\(k_2\)&lt;/span&gt; and &lt;span class="math"&gt;\(k_3\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Identifying which rotation to use by strictly based upon these four cases can work but time-consuming. Here is how I think about 
this issue from practical point of view: you may compare the insertion value with the inbalance node value to determine which node to use.
Here is the detail steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Compare the insertion value with the inbalance node value:
   if comparison result is &lt;span class="math"&gt;\(&amp;lt;\)&lt;/span&gt;, then we insert into the left subtree of inbalance node. &lt;span class="math"&gt;\(&amp;gt;\)&lt;/span&gt; otherwise.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the insertion value is &lt;span class="math"&gt;\(&amp;lt;\)&lt;/span&gt; (or &lt;span class="math"&gt;\(&amp;gt;\)&lt;/span&gt;) than the left (or right) child value of the inbalance node, we are doing single rotation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the insertion value is in-between, then we are doing double rotation. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See MAW p.117 insertion 13 for an example.&lt;/p&gt;
&lt;h2 id="deletion"&gt;Deletion&lt;/h2&gt;
&lt;p&gt;Deletion, in fact, is extremely similar to the insertion in the sense that: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is based upon BST deletion with extra treatment towards node height information and AVL property&lt;/li&gt;
&lt;li&gt;There are the same rotation cases we need to consider when we ensure the AVL property satisfied for the nodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is only one difference than insertion, which is there can be more than unbalanced node needed to be taken care of when we walk
through the deletion point to the root.&lt;/p&gt;
&lt;p&gt;There is nuance in terms of how we think about which rotation to use. In insertion, we think about in terms of insertion point. For instance,
if the insert value is smaller than unbalanced node value, and smaller than the unbalanced node’s child value, we know we are in left-left case, which is 
single rotation. However, when we deal with deletion, we actually think about the height of the subtree: a left-left insertion is equivalent as 
we make the the left subtree of unbalanced node’s child taller than its right subtree. In deletion, there is no way we can use a specific element value 
to decide what rotation we should use (like insertion). Thus, we have the following code in our &lt;code&gt;deletion&lt;/code&gt; routine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;singleRotateWithLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//Left Left case&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;doubleRotateWithLeft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//Left Right case&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Right&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="kr"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;singleRotateWithRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//Right Right case&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;doubleRotateWithRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;//Right Left case&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, the following simple example may help you understand the code chunk above:&lt;/p&gt;
&lt;p&gt;&lt;img alt="AVL-deletion" class="img-responsive" src="https://zhu45.org/images/AVL-deletion.PNG"/&gt;&lt;/p&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;For every node of the AVL tree, &lt;span class="math"&gt;\(|Height(left child) - Height(right child)| \le 1\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Running time for “find”, “insert”, “delete” is &lt;em&gt;guaranteed&lt;/em&gt; to be &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;The height of AVL tree &lt;span class="math"&gt;\(H\)&lt;/span&gt; is at most &lt;span class="math"&gt;\(1.44\log _2 N\)&lt;/span&gt;. 
  (see &lt;a href="https://zhu45.org/posts/2017/Jan/26/maw-chapter-4-tree-writing-questions/"&gt;this post&lt;/a&gt; for the proof)&lt;/li&gt;
&lt;li&gt;For an insertion, there is &lt;em&gt;at most one&lt;/em&gt; rotation (used in non-recursive insertion routine).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pros-cons-of-data-structure"&gt;Pros &amp;amp; Cons of data structure&lt;/h2&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; since AVL trees are always balanced.&lt;/li&gt;
&lt;li&gt;Insertion and deletions are also &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;The height balancing adds no more than a constant factor to the speed of insertion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Difficult to program &amp;amp; debug; more space for height information.&lt;/li&gt;
&lt;li&gt;Asymptotically faster but rebalancing costs time.&lt;/li&gt;
&lt;li&gt;Most large searches are done in database systems on disk and use
  other structures (e.g. B-trees).&lt;/li&gt;
&lt;li&gt;May be OK to have &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; for a single operation if total run time for
  many consecutive operations is fast (e.g. Splay trees). In other words,
  If &lt;em&gt;amortized&lt;/em&gt; logarithmic time is enough, use splay trees.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 4&lt;/li&gt;
&lt;li&gt;https://courses.cs.washington.edu/courses/cse373/06sp/handouts/lecture12.pdf &lt;/li&gt;
&lt;li&gt;https://courses.cs.washington.edu/courses/cse332/10sp/lectures/lecture8.pdf&lt;/li&gt;
&lt;li&gt;http://www.geeksforgeeks.org/avl-tree-set-2-deletion/&lt;/li&gt;
&lt;li&gt;http://www.mathcs.emory.edu/~cheung/Courses/323/Syllabus/Trees/AVL-delete.html&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="trees"></category><category term="maw"></category></entry><entry><title>Solving recurrence relations in a nutshell</title><link href="https://zhu45.org/posts/2017/Feb/02/solving-recurrence-relations-in-a-nutshell/" rel="alternate"></link><published>2017-02-02T01:05:00+08:00</published><updated>2017-02-02T01:05:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-02-02:/posts/2017/Feb/02/solving-recurrence-relations-in-a-nutshell/</id><summary type="html">&lt;p&gt;MATH475 methods to solve recurrence relation&lt;/p&gt;</summary><content type="html">&lt;p&gt;Able to solve recurrence relation is a very important skill when we study data structures
and algorithm. This is a ability that I used to be familar with when I took combinatorics
class when I was an undergraduate. However, by that time, I didn’t realize how important 
this skill is from computer science point of view. But, thanks to MAW, I do now.&lt;/p&gt;
&lt;p&gt;This post is a study summary note on this very important subject. The aim of this note 
is to help at least me quickly solve any types of recurrence relation in the future.
The content closely follows Chapter 7
“Recurrence Relations and Generating Functions” of 
&lt;a href="https://www.amazon.com/Introductory-Combinatorics-5th-Richard-Brualdi/dp/0136020402"&gt;“Introductory Combinatorics”&lt;/a&gt;,
which is the textbook I used.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This note is practical-oriented. I will skip the proof of the theorem 
whenever possible.If you are interested in the proof side of the universe, 
please read the book.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="toc"&gt;TOC&lt;/h2&gt;
&lt;p&gt;The post will be organized in the following format:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linear homogeneous recurrence relation with constant coefficients&lt;ul&gt;
&lt;li&gt;Method 1: Characteristic equation&lt;ul&gt;
&lt;li&gt;distinct roots (theorem 7.4.1)&lt;/li&gt;
&lt;li&gt;roots with multiplicities (theorem 7.4.2)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Method 2: Generating function&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Linear nonhomogeneous recurrence relation with constant coefficients&lt;ul&gt;
&lt;li&gt;Method 1: Characteristic equation&lt;/li&gt;
&lt;li&gt;Method 2: Generating functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="linear-homogeneous-recurrence-relation-with-constant-coefficients"&gt;Linear homogeneous recurrence relation with constant coefficients&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Definition:&lt;/em&gt; Let &lt;span class="math"&gt;\(h_0, h_1, h_2, \dots, h_n, \dots\)&lt;/span&gt; be a sequence of numbers. This sequence is 
said to satisfy a &lt;strong&gt;linear recurrence relation of order &lt;span class="math"&gt;\(k\)&lt;/span&gt;&lt;/strong&gt;, provided that there
exist quantities &lt;span class="math"&gt;\(a_1, a_2, \dots, a_k,\)&lt;/span&gt; with &lt;span class="math"&gt;\(a_k \ne 0\)&lt;/span&gt;, and a quantity &lt;span class="math"&gt;\(b_n\)&lt;/span&gt;
(each of these quantities &lt;span class="math"&gt;\(a_1,a_2,\dots,a_k,b_n\)&lt;/span&gt; may depend on &lt;span class="math"&gt;\(n\)&lt;/span&gt;) such that &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
h_n = a_1h_{n-1} + a_2h_{n-2} + \dots + a_kh_{n-k} + b_n, (n\ge k) \label{eq:1}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; The Fabonacci sequence &lt;span class="math"&gt;\(f_0, f_1, f_2, \dots, f_n, \dots\)&lt;/span&gt; satisfies
the linear recurrence relation&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
f_n = f_{n-1} + f_{n-2} (n\ge 2)
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;of order 2 with &lt;span class="math"&gt;\(a_1 = 1, a_2 = 1,\)&lt;/span&gt; and &lt;span class="math"&gt;\(b_n = 0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Definition:&lt;/em&gt; The linear recurrence relation \ref{eq:1} is called &lt;strong&gt;homogeneous&lt;/strong&gt; 
provided that &lt;span class="math"&gt;\(b_n\)&lt;/span&gt; is zero and is said to have &lt;strong&gt;constant coefficients&lt;/strong&gt; provided that
&lt;span class="math"&gt;\(a_1, a_2, \dots, a_k\)&lt;/span&gt; are constants.&lt;/p&gt;
&lt;h3 id="method-1-characteristic-equation"&gt;Method 1: Characteristic equation&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Theorem 7.4.1:&lt;/em&gt; Let &lt;span class="math"&gt;\(q\)&lt;/span&gt; be a nonzero number. Then &lt;span class="math"&gt;\(h_n = q^n\)&lt;/span&gt; is a solution of the
linear homogeneous recurrence relation&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
h_n - a_1h_{n-1}-a_2h_{n-2}- \dots - a_kh_{n-k} = 0, (a_k \ne 0, n \ge k) \label{eq:2}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;with constant coefficients iff &lt;span class="math"&gt;\(q\)&lt;/span&gt; is a root of the polynomial equation (called &lt;strong&gt;characteristic equation&lt;/strong&gt;) &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
x_k-a_1x^{k-1}-a_2x^{k-2}- \dots - a_k = 0 \label{eq:3}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;If the polynomial equation has &lt;span class="math"&gt;\(k\)&lt;/span&gt; &lt;em&gt;distinct&lt;/em&gt; roots &lt;span class="math"&gt;\(q_1, q_2, \dots, q_k\)&lt;/span&gt;, then&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
h_n = c_1q_1^{n}+c_2q_2^n+ \dots + c_kq_k^n \label{eq:4}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;is the general solution of \ref{eq:2} in the following sense: No matter what initial
values for &lt;span class="math"&gt;\(h_0, h_1, \dots, h_{k-1}\)&lt;/span&gt; are given, there are constants &lt;span class="math"&gt;\(c_1, c_2, \dots, c_k\)&lt;/span&gt;
so that \ref{eq:4} is the unique sequence which satisfies both the recurrence relation 
\ref{eq:2} and the initial values.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; Solve the Fabonacci recurrence relation&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
f_n = f_{n-1} + f_{n-2} (n\ge 2)
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;subject to the initial values &lt;span class="math"&gt;\(f_0 = 0\)&lt;/span&gt;, and &lt;span class="math"&gt;\(f_1\)&lt;/span&gt; = 1.&lt;/p&gt;
&lt;p&gt;We rewrite reccurrence relation into &lt;span class="math"&gt;\(f(n) - f(n-1) - f(n-2) = 0\)&lt;/span&gt; and the characteristic 
equation of this recurrence relation is&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
x^2 - x - 1 = 0
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;and its two roots are &lt;span class="math"&gt;\(\frac{1+\sqrt 5}{2}\)&lt;/span&gt;, &lt;span class="math"&gt;\(\frac{1-\sqrt 5}{2}\)&lt;/span&gt;, and by theorem 7.4.1,&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
f_n = c_1 \Big(\frac{1+\sqrt 5}{2}\Big)^n + c_2 \Big(\frac{1-\sqrt 5}{2}\Big)^n
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;is the general solution. We now want constants &lt;span class="math"&gt;\(c_1\)&lt;/span&gt;, and &lt;span class="math"&gt;\(c_2\)&lt;/span&gt; so that &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
\begin{cases}
c_1 \Big(\frac{1+\sqrt 5}{2}\Big) + c_2 \Big(\frac{1-\sqrt 5}{2}\Big) &amp;amp;=&amp;amp; 1 \qquad (n=1)\\
c_1 + c_2 &amp;amp;=&amp;amp; 0 \qquad (n=0)\\
\end{cases}
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;and we have &lt;span class="math"&gt;\(c_1 = \frac{1}{\sqrt 5}\)&lt;/span&gt;, and &lt;span class="math"&gt;\(c_2 = -\frac{1}{\sqrt 5}\)&lt;/span&gt;. Thus,&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
f_n = \frac{1}{\sqrt 5}\Big(\frac{1+\sqrt 5}{2}\Big)^n - \frac{1}{\sqrt 5}\Big(\frac{1-\sqrt 5}{2}\Big)^n
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;is the solution of the Fabonacci recurrence relation.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;As you might notice, theorem 7.4.1 explicitly requires that the roots of the 
characteristic equation have to be distinct. However, that’s not always the case 
and theorem 7.4.1 will not work (see book for an example). 
That’s why we need theorem 7.4.2.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Theorem 7.4.2:&lt;/em&gt; Let &lt;span class="math"&gt;\(q_1, q_2, \dots, q_n\)&lt;/span&gt; be the distinct roots of the following characteristic equation of the 
linear homogeneous recurrence relation with constant coefficients:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
h_n = a_1h_{n-1}+a_2h_{n-2}+ \dots + a_kh_{n-k}, a_k \ne 0, \qquad (n \ge k) \label{eq:5}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(q_i\)&lt;/span&gt; is an &lt;span class="math"&gt;\(s_i\)&lt;/span&gt;-fold root fo the characteristic equation of \ref{eq:5}, the part of the general solution of this recurrence 
relation corresponding to &lt;span class="math"&gt;\(q_i\)&lt;/span&gt; is &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
H_{n}^{(i)} = c_1q_i^n + c_2nq_i^n + \dots + c_{s_i}n^{s_i-1}q_i^n
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;The general solution of the recurrence relation is &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
h_n = H_n^{(1)} + H_n^{(2)} + \dots + H_n^{(t)}
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; Solve the recurrence relation&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
h_n = -h_{n-1} + 3h_{n-2}+5h_{n-3}+2h_{n-4} \qquad (n \ge 4)
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;subject to the initial values &lt;span class="math"&gt;\(h_0=1\)&lt;/span&gt;, &lt;span class="math"&gt;\(h_1 = 0\)&lt;/span&gt;, &lt;span class="math"&gt;\(h_2 = 1\)&lt;/span&gt;, and &lt;span class="math"&gt;\(h_3 = 2\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The characteristic equation of this recurrence relation is &lt;span class="math"&gt;\(x^4 + x^3 -3x^2 - 5x - 2 = 0\)&lt;/span&gt;, which has roots &lt;span class="math"&gt;\(-1\)&lt;/span&gt;, &lt;span class="math"&gt;\(-1\)&lt;/span&gt;, &lt;span class="math"&gt;\(-1\)&lt;/span&gt;, &lt;span class="math"&gt;\(-2\)&lt;/span&gt;.
Thus, the part of the general solution corresponding to the root &lt;span class="math"&gt;\(-1\)&lt;/span&gt; is&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
H_n^{(1)} = c_1(-1)^n + c_2n(-1)^n + c_3n^2(-1)^n
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;while the part of a general solution corresponding to the root &lt;span class="math"&gt;\(2\)&lt;/span&gt; is &lt;span class="math"&gt;\(H_n^{(2)} = c_42^n\)&lt;/span&gt;. The general solution is &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
h_n = H_n^{(1)} + H_n^{(2)} = c_1(-1)^n + c_2n(-1)^n + c_3n^2(-1)^n + c_42^n
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Then we can use initial values to determine &lt;span class="math"&gt;\(c1\)&lt;/span&gt;, &lt;span class="math"&gt;\(c2\)&lt;/span&gt;, &lt;span class="math"&gt;\(c3\)&lt;/span&gt;, &lt;span class="math"&gt;\(c4\)&lt;/span&gt; and we have &lt;span class="math"&gt;\(h_n = \frac{7}{9} (-1)^n - \frac{3}{9}n(-1)^n + \frac{2}{9}2^n\)&lt;/span&gt;.&lt;/p&gt;
&lt;!--
&gt; You probably already notice from the previous example that "characteristic equation" method really depends on the diffculty in finding all roots
&gt; of a polynomial equation. Sometimes finding the roots of characteristic equation can be quite diffcult. That's what second method tries to address.
&gt; If you find out that characteristic equation is really diffcult to solve, you can always use "generating function" method.--&gt;
&lt;h3 id="method-2-generating-function"&gt;Method 2: Generating function&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Definition:&lt;/em&gt; Let &lt;span class="math"&gt;\(h_0, h_1, h_2, \dots, h_n, \dots\)&lt;/span&gt; be an infinite sequence of numbers. Its &lt;strong&gt;generating function&lt;/strong&gt; is defined to be the infinite
series&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
g(x) = h_0 + h_1x + h_2x^2 + \dots + h_nx^n + \cdots
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;The coefficient of &lt;span class="math"&gt;\(x^n\)&lt;/span&gt; in &lt;span class="math"&gt;\(g(x)\)&lt;/span&gt; is the general solution to &lt;span class="math"&gt;\(h_n\)&lt;/span&gt;. As you can see, generating functions are Taylor series (power series expansion)
of infinitely differentiable functions. If we can find the function (i.e. &lt;span class="math"&gt;\(g(x)\)&lt;/span&gt;) and its Taylor series, then the coefficients of the Taylor series give the solution 
to the problem.&lt;/p&gt;
&lt;p&gt;Let’s illustrate this method using an example.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; Solve the recurrence relation &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
h_n = 5h_{n-1} - 6h_{n-2} \qquad (n \ge 2) 
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;subject to the initial values &lt;span class="math"&gt;\(h_0 = 1\)&lt;/span&gt; and &lt;span class="math"&gt;\(h_1 = -2\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;We first rewrite the recurrence relation into &lt;span class="math"&gt;\(h_n -5h_{n-1} + 6h_{n-2} = 0 \quad (n \ge 2)\)&lt;/span&gt;. Let &lt;span class="math"&gt;\(g(x) = h_0 + h_1x + h_2x^2 + \dots + h_nx^n + \cdots\)&lt;/span&gt;
be the generating function for the sequence &lt;span class="math"&gt;\(h_0, h_1, \dots, h_n, \dots\)&lt;/span&gt;. We then form the following system of equations with the multipliers chosen based 
upon our rewritten recurrence relation initially.&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
g(x) &amp;amp;=&amp;amp; h_0 + h_1x + h_2x^2 + \dots + h_nx^n + \cdots \\
-5xg(x) &amp;amp;=&amp;amp;   -5h_0x - 5h_1x^2 - \dots - 5h_{n-1}x^n - \cdots \\
6x^2g(x) &amp;amp;=&amp;amp;         6h_0x^2 + \dots + 6h_{n-2}x^n + \cdots
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;If you look at the coefficients of &lt;span class="math"&gt;\(x^n\)&lt;/span&gt; term vertically of all these three equations, you can see that they match our recurrence relation exactly.
Now, we add these three equations together, we obtain&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
(1-5x+6x^2)g(x) = h_0 + (h_1-5h_0)x + (h_2 - 5h_1 + 6h_0)x^2 + \dots + (h_n - 5h_{n-1} + 6h_{n-2})x^n + \cdots .
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;since &lt;span class="math"&gt;\($h_n - 5h_{n-1} + 6h_{n-2} = 0 \quad (n \ge 2)\)&lt;/span&gt; and our initial condition, we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
(1-5x+6x^2)g(x) = h_0 + (h_1 - 5h_0)x = 1 -7x
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Thus,&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
g(x) = \frac{1-7x}{1-5x+6x^2}
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Now, we need to expand &lt;span class="math"&gt;\(g(x)\)&lt;/span&gt; in order to get the coefficient of &lt;span class="math"&gt;\(h_n\)&lt;/span&gt;. Since &lt;span class="math"&gt;\(1-5x+6x^2 = (1-2x)(1-3x)\)&lt;/span&gt;, we can write&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
\frac{1-7x}{1-5x+6x^2} = \frac{c_1}{1-2x} + \frac{c_2}{1-3x}
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;for some constants &lt;span class="math"&gt;\(c1\)&lt;/span&gt; and &lt;span class="math"&gt;\(c2\)&lt;/span&gt;. We can determine &lt;span class="math"&gt;\(c1\)&lt;/span&gt; and &lt;span class="math"&gt;\(c2\)&lt;/span&gt; by multiplying both sides of this equation by &lt;span class="math"&gt;\(1-5x+6x^2\)&lt;/span&gt; to get&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
1 - 7x = (c_1 + c_2) + (-3c_1 -2c_2)x
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;We can get &lt;span class="math"&gt;\(c_1 = 5\)&lt;/span&gt; and &lt;span class="math"&gt;\(c_2 = -4\)&lt;/span&gt;. Since &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
\frac{1}{(1-rx)^n} = \sum_{k=0}^\infty\dbinom{n+k-1}{k}r^kx^k \qquad \Big(|x| &amp;lt; \frac{1}{|r|}\Big)
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;We have &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
\frac{1}{1-2x} = 1 + 2x + 2^2x^2 + \dots + 2^nx^n + \cdots
\end{equation*}
$$&lt;/div&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
\frac{1}{1-3x} = 1 + 3x + 3^2x^2 + \dots + 3^nx^n + \cdots
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;So&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
g(x) &amp;amp;=&amp;amp; 5(1 + 2x + 2^2x^2 + \dots + 2^nx^n + \cdots) -4(1 + 3x + 3^2x^2 + \dots + 3^nx^n + \cdots) \\
&amp;amp;=&amp;amp; 1 + (-2)x + (-15)x^2 + \dots + (5\times2^n - 4\times3^n)x^n + \cdots
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Thus, &lt;span class="math"&gt;\(h_n = 5\times2^n - 4\times3^n\)&lt;/span&gt;.&lt;/p&gt;
&lt;!-- Getting the polynomial expansion of $g(x)$ is the hardest part of this method. For instance, factoring the 
denominator of $g(x)$ can be tricky for high degree polynomials. I need more practice on solving recurrence
relation to decide which method is superior under what kind of situation.--&gt;
&lt;h2 id="linear-nonhomogeneous-recurrence-relation-with-constant-coefficients"&gt;Linear nonhomogeneous recurrence relation with constant coefficients&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;nonhomogeneous&lt;/strong&gt; means &lt;span class="math"&gt;\(b_n\)&lt;/span&gt; in \ref{eq:1} is no longer zero constant.&lt;/p&gt;
&lt;h3 id="method-1-characteristic-equation_1"&gt;Method 1: Characteristic equation&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Steps:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;1) Find the general solution of the homogeneous relation.&lt;/p&gt;
&lt;p&gt;2) Find a particular solution of the nonhomogeneous relation.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(b_n\)&lt;/span&gt; is a polynomial of degree &lt;span class="math"&gt;\(k\)&lt;/span&gt; in &lt;span class="math"&gt;\(n\)&lt;/span&gt;, then look for a particular solution &lt;span class="math"&gt;\(h_n\)&lt;/span&gt; that is also a polynomial of degree &lt;span class="math"&gt;\(k\)&lt;/span&gt; in &lt;span class="math"&gt;\(n\)&lt;/span&gt;. Thus, try &lt;ul&gt;
&lt;li&gt;&lt;span class="math"&gt;\(h_n = r\)&lt;/span&gt; (a constant) if &lt;span class="math"&gt;\(b_n = d\)&lt;/span&gt; (a constant)&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(h_n = rn + s\)&lt;/span&gt; if &lt;span class="math"&gt;\(b_n = dn + e\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="math"&gt;\(h_n = rn^2 + sn + t\)&lt;/span&gt; if &lt;span class="math"&gt;\(b_n = dn^2 + en + f\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If &lt;span class="math"&gt;\(b_n\)&lt;/span&gt; is an exponential, then look for a particular solution that is also an exponential. Thus, try &lt;span class="math"&gt;\(h_n = pd^n\)&lt;/span&gt; if &lt;span class="math"&gt;\(b_n = d^n\)&lt;/span&gt; or &lt;span class="math"&gt;\(h_n = pnd^n\)&lt;/span&gt; if 
  the first try doesn’t work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3) Combine the general solution and the particular solution so that the combined solution satisfies the initial conditions.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Example:&lt;/em&gt; Solve &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
h_n &amp;amp;=&amp;amp; 3h_{n-1} - 4n, \qquad (n \ge 1) \\
h_0 &amp;amp;=&amp;amp; 2
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;We first consider corresponding homogeneous recurrence relation &lt;span class="math"&gt;\(h_n = 3h_{n-1}\)&lt;/span&gt; and its characteristic equation is &lt;span class="math"&gt;\(x - 3 = 0\)&lt;/span&gt;. and thus
we have the general solution &lt;span class="math"&gt;\(h_n = c3^n, \quad (n \ge 1)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Now we seek a particular solution of the nonhomogeneous recurrence relation &lt;span class="math"&gt;\(h_n = 3h_{n-1}-4n, \quad (n \ge 1)\)&lt;/span&gt;. We try to find a solution of the 
form &lt;span class="math"&gt;\(h_n = rn + s\)&lt;/span&gt; for some constant number &lt;span class="math"&gt;\(r\)&lt;/span&gt; and &lt;span class="math"&gt;\(s\)&lt;/span&gt;. We plug in our conjecture into the recurrence relation and get&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
rn + s = 3(r(n-1)+s) - 4n = (3r-4)n + (-3r+3s)
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Thus, &lt;span class="math"&gt;\(r = 2\)&lt;/span&gt; and &lt;span class="math"&gt;\(s = 3\)&lt;/span&gt; and &lt;span class="math"&gt;\(h_n = 2n + 3\)&lt;/span&gt;. Now, we combine the general solution of the homogeneous relation with the particular solution 
of the nonhomogeneous relation to obtain&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
h_n = c3^n + 2n + 3
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Now, let’s use inital condition to solve for &lt;span class="math"&gt;\(c\)&lt;/span&gt; and we have &lt;span class="math"&gt;\(c = -1\)&lt;/span&gt;. So, &lt;span class="math"&gt;\(h_n = -3^n + 2n + 3\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;As you can see, solving recurrence relation using characteristic equation has 
strong connection with solving differential equations (both homogeneous and 
nonhomogeneous). &lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="method-2-generating-function_1"&gt;Method 2: Generating function&lt;/h3&gt;
&lt;p&gt;There is nothing difference in using “generating function” method to solve nonhomogeneous than solve homogeneous recurrence relation. That’s actually 
a beauty of this method: nothing needs to tweak in order to work under different situation.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Certainly, not all recurrence relation appeard in computer science can be easily 
solved by the method described in this post. For instance, inside 
&lt;a href="https://zhu45.org/posts/2016/Dec/31/josephus-problem/"&gt;Josephus problem&lt;/a&gt;, recurrence 
relation may depend on whether &lt;span class="math"&gt;\(n\)&lt;/span&gt; is odd or even and 
methods may not apply nicely. This implies another type of technique to solve 
recurrence relation is to guess the solution and prove it by induction.
Also, in the book, solving &lt;span class="math"&gt;\(h_n = h_{n-1} + n^3\)&lt;/span&gt; on p. 250 is not standard as 
well.&lt;/p&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Mathematics"></category><category term="recursion"></category><category term="combinatorics"></category><category term="math"></category></entry><entry><title>Binary Tree &amp; Binary Search Tree</title><link href="https://zhu45.org/posts/2017/Jan/29/binary-tree-binary-search-tree/" rel="alternate"></link><published>2017-01-29T13:20:00+08:00</published><updated>2017-01-29T13:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-29:/posts/2017/Jan/29/binary-tree-binary-search-tree/</id><summary type="html">&lt;p&gt;Binary tree and binary search tree summary&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is the summary of &lt;em&gt;binary tree&lt;/em&gt; and &lt;em&gt;binary search tree&lt;/em&gt; part in MAW Chapter 4.&lt;/p&gt;
&lt;div class="toc"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#concept"&gt;Concept&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#classification-of-binary-trees"&gt;Classification of binary trees&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#properties"&gt;Properties&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#selected-proofs"&gt;Selected Proofs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reference"&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id="concept"&gt;Concept&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;binary tree&lt;/em&gt; is a tree in which no node can have more than two children. &lt;/li&gt;
&lt;li&gt;An important application of binary trees is &lt;em&gt;binary search tree&lt;/em&gt;: for every node,
  &lt;span class="math"&gt;\(X\)&lt;/span&gt;, in the tree, the values of all the keys in its left subtree are smaller than
  the key value in &lt;span class="math"&gt;\(X\)&lt;/span&gt;, and the values of all the keys in its right subtree are larger
  than the key value in &lt;span class="math"&gt;\(X\)&lt;/span&gt; (&lt;em&gt;BST-property&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="classification-of-binary-trees"&gt;Classification of binary trees&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;full&lt;/em&gt; binary tree (proper binary tree or 2-tree) is a binary tree in which each node
  has exactly zero or two children.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;full node&lt;/em&gt; in a binary tree is a node that has exactly two non-null children.&lt;/p&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;complete&lt;/em&gt; binary tree is a binary tree, which is completely filled, with the possible
  exception of the bottom level, which is filled from left to right.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="full-complete-binary-tree" class="img-responsive" src="https://zhu45.org/images/full-complete-binary-tree.PNG"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;perfect&lt;/em&gt; binary tree: A binary tree in which all internal nodes have exactly two children 
  and all leaves are at the same level. It has property: each level has exactly twice as many 
  nodes as the previous level (since each internal node has exactly two children).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="perfect-binary-tree" class="img-responsive" src="https://zhu45.org/images/perfect-binary-tree.png"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;em&gt;balance&lt;/em&gt; binary tree: a binary tree structure in which the left and right 
  subtrees of every node differ in height by no more than 1. Yes, &lt;a href="https://zhu45.org/posts/2017/Feb/05/avl-tree/"&gt;AVL tree&lt;/a&gt;
  definition.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="properties"&gt;Properties&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The average depth of binary tree is &lt;span class="math"&gt;\(O(\sqrt{n})\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;The height of &lt;em&gt;balance&lt;/em&gt; binary tree is &lt;span class="math"&gt;\(O(\log n)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;A complete binary tree on &lt;span class="math"&gt;\(n\)&lt;/span&gt; nodes has height &lt;span class="math"&gt;\(\lfloor \log n \rfloor\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;A binary tree of &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes, there are &lt;span class="math"&gt;\(N+1\)&lt;/span&gt; &lt;code&gt;NULL&lt;/code&gt; pointers representing children (MAW 4.4)&lt;/li&gt;
&lt;li&gt;The maximum number of nodes in a binary tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt; is &lt;span class="math"&gt;\(2^{H+1}-1\)&lt;/span&gt; (MAW 4.5)&lt;ul&gt;
&lt;li&gt;A perfect binary tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt; contains exactly &lt;span class="math"&gt;\(2^{H+1}-1\)&lt;/span&gt; nodes, of which &lt;span class="math"&gt;\(2^H\)&lt;/span&gt; are leaves.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The number of full nodes plus one is equal to the number of leaves in a nonempty binary tree&lt;/li&gt;
&lt;li&gt;The average depth of a node in a binary search tree constructed from random data is &lt;span class="math"&gt;\(O(\log n)\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;The average of height of a random binary search tree is &lt;span class="math"&gt;\(O(\log n)\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(E[h] = O(\log n)\)&lt;/span&gt;) (MAW 4.14)&lt;/li&gt;
&lt;li&gt;All the basic operations &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;findMin&lt;/code&gt;, &lt;code&gt;findMax&lt;/code&gt;, &lt;code&gt;insert&lt;/code&gt;, and &lt;code&gt;delete&lt;/code&gt;
&lt;span class="math"&gt;\(O(H)\)&lt;/span&gt; time, where &lt;span class="math"&gt;\(H\)&lt;/span&gt; is the height of the tree.&lt;ul&gt;
&lt;li&gt;worst case: height &lt;span class="math"&gt;\(H = n - 1\)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;base case: height &lt;span class="math"&gt;\(H = \log N\)&lt;/span&gt;, where the tree is a complete binary tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Randomly built binary search trees:&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;average height&lt;/em&gt; is much closer to the best case.&lt;/li&gt;
&lt;li&gt;Little is known about the average height when &lt;em&gt;both insertion and deletion&lt;/em&gt; are used.&lt;/li&gt;
&lt;li&gt;characteristics&lt;ul&gt;
&lt;li&gt;Keys inserting in &lt;em&gt;random order&lt;/em&gt; into an initially empty tree.&lt;/li&gt;
&lt;li&gt;Each of the &lt;span class="math"&gt;\(n!\)&lt;/span&gt; &lt;em&gt;permutations&lt;/em&gt; of the input keys is &lt;em&gt;equally likely&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="selected-proofs"&gt;Selected Proofs&lt;/h2&gt;
&lt;p&gt;Let’s prove “The number of full nodes plus one is equal to the number of leaves in a nonempty binary tree” using induction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Let &lt;span class="math"&gt;\(n\)&lt;/span&gt; be the number of full nodes and &lt;span class="math"&gt;\(m\)&lt;/span&gt; be the number of leaves in a nonempty binary tree. Then, we have &lt;span class="math"&gt;\(n + 1 = m\)&lt;/span&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Base case: &lt;span class="math"&gt;\(n = 0\)&lt;/span&gt;, since the binary tree is nonempty, we have the degenerated binary tree with &lt;span class="math"&gt;\(m = 1\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Recursion: Suppose the claim holds for &lt;span class="math"&gt;\(n\)&lt;/span&gt; (i.e., &lt;span class="math"&gt;\(n + 1 = m\)&lt;/span&gt;. We want to show that the claim also holds for &lt;span class="math"&gt;\(n+1\)&lt;/span&gt;. There are two cases we need to consider:&lt;ul&gt;
&lt;li&gt;We add two leaves to form one extra full node. In this case, we have &lt;span class="math"&gt;\(m - 1 + 2 = m+1\)&lt;/span&gt; leaves. Thus, we have 
&lt;span class="math"&gt;\(m+1 - (n+1) = n+1+1 - (n+1) = 1\)&lt;/span&gt;. The claim holds.&lt;/li&gt;
&lt;li&gt;We add one leaf to form one extra full node. In this case, we have &lt;span class="math"&gt;\(m + 1\)&lt;/span&gt; leaves. Thus, we have
&lt;span class="math"&gt;\(m+1 - (n+1) = 1\)&lt;/span&gt;. The claim holds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MAW Chapter 4&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Binary_tree"&gt;Binary Tree Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/trees.html"&gt;Binary Tree CMU page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="trees"></category><category term="maw"></category></entry><entry><title>MAW Chapter 4: Tree writing questions</title><link href="https://zhu45.org/posts/2017/Jan/26/maw-chapter-4-tree-writing-questions/" rel="alternate"></link><published>2017-01-26T17:41:00+08:00</published><updated>2017-01-26T17:41:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-26:/posts/2017/Jan/26/maw-chapter-4-tree-writing-questions/</id><summary type="html">&lt;p&gt;My solutions to selected problems in MAW Chapter 4&lt;/p&gt;</summary><content type="html">&lt;p&gt;There are a lot of writing questions in Chapter 4. Some questions offer
great insights on the general techniques in solving algorithmatic proving questions.
So, I decide to record them in this single post. Of course, this post will be continually
updated as I work through the chapter.&lt;/p&gt;
&lt;h2 id="insights"&gt;Insights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Recursive tree definition is a natural fit with induction (i.e., MAW 4.5, 4.6, 4.7).&lt;/li&gt;
&lt;li&gt;Usually there are two ways to prove a problem in tree, one direction is from induction
  and the other one is from basic tree property (i.e., MAW 4.4, 4.6).&lt;/li&gt;
&lt;li&gt;Combinatorics (relating to binomials) and Probability theory (discrete part) are important to look at (i.e., MAW 4.14)&lt;/li&gt;
&lt;li&gt;We can usually study some specific examples, and try to generalize them to form induction proof. 
  In addition, always remember we want to convert the problem for &lt;span class="math"&gt;\(n+1\)&lt;/span&gt; into the same problem but 
  with the inductive step on &lt;span class="math"&gt;\(n\)&lt;/span&gt;. (MAW 4.17)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="solutions"&gt;Solutions&lt;/h2&gt;
&lt;p&gt;including: MAW 4.4, 4.5, 4.6, 4.7, 4.14, 4.15, 4.16, 4.17, 4.23, 4.24, 4.25, 4.26.a, 4.43&lt;/p&gt;
&lt;h3 id="maw-44"&gt;MAW 4.4&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Show that in a binary tree of &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes, there are &lt;span class="math"&gt;\(N + 1\)&lt;/span&gt; &lt;code&gt;NULL&lt;/code&gt; pointers
representing children.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
For a binary tree with &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes, there are two types of edges (pointers): &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;edges that are doesn’t exist (&lt;code&gt;NULL&lt;/code&gt; pointers).&lt;/li&gt;
&lt;li&gt;edges that exist to connect nodes (not &lt;code&gt;NULL&lt;/code&gt; pointers).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s first calculate the number of pointers in total, regardless whether the pointer
is &lt;code&gt;NULL&lt;/code&gt; or not. Since each node has &lt;span class="math"&gt;\(2\)&lt;/span&gt; outgoing pointers, 
there are &lt;span class="math"&gt;\(2N\)&lt;/span&gt; pointers in total. Next, we need to calculate the number of edges that actuall
exist. Since each edge connects some node to its parent, and every node except 
the root has one parent. In other words, each node, except the root node, has one incoming
pointer from its parent. So, we have &lt;span class="math"&gt;\(N-1\)&lt;/span&gt; edges existing. Thus the remaining
&lt;span class="math"&gt;\(2N - (N-1) = N+1\)&lt;/span&gt; edges are actually non-existing. Thus, we have &lt;span class="math"&gt;\(N+1\)&lt;/span&gt; &lt;code&gt;NULL&lt;/code&gt; pointers.&lt;/p&gt;
&lt;h3 id="maw-45"&gt;MAW 4.5&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Show that the maximum number of nodes in a binary tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt; is &lt;span class="math"&gt;\(2^{H+1}-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt; 
Let’s prove this by induction.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Base case:&lt;/em&gt; &lt;span class="math"&gt;\(H = 0\)&lt;/span&gt;. A binary tree of height &lt;span class="math"&gt;\(0\)&lt;/span&gt; has only one node, root. &lt;span class="math"&gt;\(2^{H+1}-1\)&lt;/span&gt; equals
one for &lt;span class="math"&gt;\(H = 0\)&lt;/span&gt;. Therefore ture for &lt;span class="math"&gt;\(H = 0\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Inductive Hypothesis:&lt;/em&gt; Assume that the maximum number of nodes in a binary tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt; is
&lt;span class="math"&gt;\(2^{H+1}-1\)&lt;/span&gt; for &lt;span class="math"&gt;\(H = 1, 2, ..., k\)&lt;/span&gt;. Consider a tree &lt;span class="math"&gt;\(T\)&lt;/span&gt; of height &lt;span class="math"&gt;\(k+1\)&lt;/span&gt;. The root of &lt;span class="math"&gt;\(T\)&lt;/span&gt; has 
a left subtree and a right subtree each of which has height at most &lt;span class="math"&gt;\(k\)&lt;/span&gt;. These can have
at most &lt;span class="math"&gt;\(2^{k+1}-1\)&lt;/span&gt; nodes each by the inductive hypothesis. Adding the root node gives the 
maximum number of nodes in a binary tree of height &lt;span class="math"&gt;\(k+1\)&lt;/span&gt;, &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation} 
2(2^{k+1} - 1) + 1 = 2^{(k+1)+1} - 1 
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;Remarks:&lt;/p&gt;
&lt;p&gt;The maximum condition achieves when we have &lt;em&gt;perfect binary tree&lt;/em&gt;.&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
n = \sum_{i=0}^{h} 2^i = 2^{h+1} - 1 \text{where n is the number of nodes} 
\end{equation}
$$&lt;/div&gt;
&lt;h3 id="maw-46"&gt;MAW 4.6&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;A &lt;em&gt;full node&lt;/em&gt; is a node with two children. Prove that the number of full nodes
plus one is equal to the number of leaves in a nonempty binary tree.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s use two methods to prove this question.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Method 1:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
Let’s use the following notation for our proof:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
N &amp;amp; = &amp;amp; \text{number of nodes in a nonempty binary tree} \\
F &amp;amp; = &amp;amp; \text{number of full nodes} \\
H &amp;amp; = &amp;amp; \text{number of nodes with one child} \\
L &amp;amp; = &amp;amp; \text{number of leaves}
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Then, we have &lt;span class="math"&gt;\(N = F + H + L \label{eq:1}\)&lt;/span&gt;. We can get another equation based on the number of 
edges: &lt;span class="math"&gt;\(N - 1 = 2F + H \label{eq:2}\)&lt;/span&gt;. &lt;span class="math"&gt;\(N-1\)&lt;/span&gt; is the number of edges for a &lt;span class="math"&gt;\(N\)&lt;/span&gt; node binary tree 
and &lt;span class="math"&gt;\(2F + H\)&lt;/span&gt; is another way to calculate the number of edges. Now based on these 
two euqations we have:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
2F + H + 1 &amp;amp; = &amp;amp; F + H + L \\
F + 1 &amp;amp; = &amp;amp; L
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Method 2:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
Let’s prove by induction. If there are &lt;span class="math"&gt;\(N\)&lt;/span&gt; full nodes in a non-empty binary tree
then there are &lt;span class="math"&gt;\(N+1\)&lt;/span&gt; leaves.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Base case:&lt;/em&gt; &lt;span class="math"&gt;\(N = 0\)&lt;/span&gt; This is ture because the tree has one node and the root is 
a leaf.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Inductive hypothesis:&lt;/em&gt; Suppose the theorem holds for &lt;span class="math"&gt;\(N = 1, 2, ..., k\)&lt;/span&gt;. Then we 
want to show that if there are &lt;span class="math"&gt;\(k+1\)&lt;/span&gt; full nodes in a non-empty binary tree then there 
are &lt;span class="math"&gt;\(k+2\)&lt;/span&gt; leaves. Pick a leaf node and keep removing its parent recursively 
(i.e., remove its parent and then parent’s parent and so on) until a full node
is reached. That is, you are traversing from a leaf along the path towards the root,
while removing the nodes along the path before a full node is reached. This full node
becomes a non-full node because one of its child node is removed. At this point the
tree will have one less leaf and one less full node.&lt;/p&gt;
&lt;p&gt;&lt;img alt="MAW problem 4.6 illustration" class="img-responsive" src="https://zhu45.org/images/maw-4-6.PNG"/&gt;&lt;/p&gt;
&lt;p&gt;Therefore, the tree has &lt;span class="math"&gt;\(k\)&lt;/span&gt; full nodes after the nodes are removed. By the inductive
hypothesis there are &lt;span class="math"&gt;\(k+1\)&lt;/span&gt; leaves. Add all the nodes that were removed back into the 
tree the same way to create the original tree. We are adding one full node and 
one leaf node. Therefore, we have &lt;span class="math"&gt;\(k+1\)&lt;/span&gt; full nodes with &lt;span class="math"&gt;\(k+2\)&lt;/span&gt; leaves.&lt;/p&gt;
&lt;h3 id="maw-47"&gt;MAW 4.7&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose a binary tree has leaves &lt;span class="math"&gt;\(l_{1}, l_{2}, ..., l_{M}\)&lt;/span&gt; at depths
&lt;span class="math"&gt;\(d_{1}, d_{2}, ...,d_{M}\)&lt;/span&gt;, repectively. Prove that &lt;span class="math"&gt;\(\sum_{i=1}^M 2^{-d_{i}} \leq 1\)&lt;/span&gt;
and determine when the quality is true.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
Let’s prove this by induction. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Base case:&lt;/em&gt; when &lt;span class="math"&gt;\(M = 1\)&lt;/span&gt;, there is one node: the root is a leaf wit depth zero. Then
the sum is one, and claim holds.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Inductive hypothesis:&lt;/em&gt; Suppose the theorem is true for all trees with at most &lt;span class="math"&gt;\(k\)&lt;/span&gt; nodes.
Consider any tree with &lt;span class="math"&gt;\(k+1\)&lt;/span&gt; nodes. Such a tree consists of an &lt;span class="math"&gt;\(i\)&lt;/span&gt; node left subtree and 
a &lt;span class="math"&gt;\(k-i\)&lt;/span&gt; node right subtree. By the inductive hypothesis, the sum for the left subtree
leaves is at most one with respect to the left tree root. Because all leaves are one deeper
with respect to the original tree than with respect to the subtree, the sum is at
most &lt;span class="math"&gt;\(1/2\)&lt;/span&gt; with respect to the root. Similar logic implies that the sum for leaves 
in the right subtree is at most &lt;span class="math"&gt;\(1/2\)&lt;/span&gt; proving the theorem.&lt;/p&gt;
&lt;p&gt;The equality is true if and only if every internal node is a full node. In other words,
no nodes have one child. Suppose there is a node with one child, and the equality still
holds. Each time we remove two nodes to create a new tree that has a node with no child.
This new tree has the same property has the previous one, and by the statement we proved
above, we should have the same sum as the old, which is one. Eventually, we are left
with two node, one of them is root. Now, we calculate the sum, which gives &lt;span class="math"&gt;\(1/2\)&lt;/span&gt;. This 
is contradiction to the equality.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This problem is called 
&lt;a href="https://en.wikipedia.org/wiki/Kraft%E2%80%93McMillan_inequality"&gt;Kraft–McMillan inequality&lt;/a&gt;,
which is one of fundamental theorem in Information theory. I find 
&lt;a href="https://www.youtube.com/playlist?list=PLE125425EC837021F"&gt;this youtube playlist about information theory&lt;/a&gt;
is really good as an intro to the field because it doesn’t make the material look 
very daunting and super technical,
which some 
&lt;a href="http://circuit.ucsd.edu/~yhk/ece154c-spr16/pdfs/LectureNotes01.pdf"&gt;lecture note&lt;/a&gt;
 manages to achieve.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="maw-414"&gt;MAW 4.14&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Prove that the depth of a random binary search tree (depth of the deepest node) is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;, on average.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This question can be restated like the following: suppose that we insert &lt;span class="math"&gt;\(n\)&lt;/span&gt; distinct elements into an 
initially empty tree. Assuming that the &lt;span class="math"&gt;\(n!\)&lt;/span&gt; permutations are equally likely to occur, then show that
the average height of the tree is &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Before we dive into the proof, let’s think about how we can construct a random binary search tree.
We construct a tree &lt;span class="math"&gt;\(T\)&lt;/span&gt; by inserting in order randomly selected &lt;span class="math"&gt;\(n\)&lt;/span&gt; distinct elements into an 
initially empty tree. Here the actual values of the elements do not matter. What matters is the position
of the inserted element in the &lt;span class="math"&gt;\(n\)&lt;/span&gt; elements. Thus, we construct a random binary search tree as the following:&lt;/p&gt;
&lt;p&gt;An element &lt;span class="math"&gt;\(i\)&lt;/span&gt; from the &lt;span class="math"&gt;\(n\)&lt;/span&gt; elements is selected uniformly ar random and is inserted to the empty tree. Then all 
the other elements are inserted. Here all the elements greater than &lt;span class="math"&gt;\(i\)&lt;/span&gt; go into the right subtree of &lt;span class="math"&gt;\(i\)&lt;/span&gt;
and all the elements smaller than &lt;span class="math"&gt;\(i\)&lt;/span&gt; go into the left subtree. Thus, the height of the tree constructed
is one plus the larger of the height of the left subtree and the height of the right subtree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
Following our construction process above, if we randomly choose the &lt;span class="math"&gt;\(i^{th}\)&lt;/span&gt; key, the left
subtree has &lt;span class="math"&gt;\(i-1\)&lt;/span&gt; elements and the right subtree has &lt;span class="math"&gt;\(n-i\)&lt;/span&gt; elements. Let &lt;span class="math"&gt;\(h_{n}\)&lt;/span&gt; be the
height of a randomly built binary search tree on &lt;span class="math"&gt;\(n\)&lt;/span&gt; keys. Then we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation} 
h_{n} = 1 + max(h_{i-1}, h_{n-i}) \label{eqn:1}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;Now, let’s define &lt;span class="math"&gt;\(Y_{n} = 2^{h_n}\)&lt;/span&gt;. If we can show 
that &lt;span class="math"&gt;\(E[Y_n]\)&lt;/span&gt; is polynomial in &lt;span class="math"&gt;\(n\)&lt;/span&gt;, we then have &lt;span class="math"&gt;\(E[h_n] = O(\log n)\)&lt;/span&gt;. Again, &lt;span class="math"&gt;\(Y_n\)&lt;/span&gt; 
depends on &lt;span class="math"&gt;\(i\)&lt;/span&gt; not &lt;span class="math"&gt;\(n\)&lt;/span&gt;. Let’s represent \ref{eqn:1} in terms of &lt;span class="math"&gt;\(Y_n\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
h_{n} &amp;amp;=&amp;amp; 1 + max(h_{i-1}, h_{n-i}) \\
2^{h_n} &amp;amp;=&amp;amp; 2^{1 + max(h_{i-1}, h_{n-i})} \\
        &amp;amp;=&amp;amp; 2 \cdot 2^{max(h_{i-1}, h_{n-i})} \\
        &amp;amp;=&amp;amp; 2 \cdot max(2^{h_{i-1}}, 2^{h_{n-i}}) \\
Y_n     &amp;amp;=&amp;amp; 2 \cdot max(Y_{i-1}, Y_{n-i}) 
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Now, let’s calculate &lt;span class="math"&gt;\(E[Y_n]\)&lt;/span&gt;. Here, &lt;span class="math"&gt;\(I=i\)&lt;/span&gt; means we pick &lt;span class="math"&gt;\(i_{th}\)&lt;/span&gt; element as our 
first element inserting into the empty tree.Since, we pick the first insertion element equally
likely, then &lt;span class="math"&gt;\(P(I=i) = \frac{1}{n}\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
E[Y_n] &amp;amp;=&amp;amp; \sum_{i=1}^n E[Y_n|I=i]P(I=i) \\
       &amp;amp;=&amp;amp; \sum_{i=1}^n E[Y_n|I=i]\frac{1}{n} \\
       &amp;amp;=&amp;amp; \frac{2}{n}\sum_{i=1}^n E[max(Y_{i-1},Y_{n-i})] \\
       &amp;amp;\le&amp;amp; \frac{2}{n}\sum_{i=1}^n (E[Y_{i-1}] + E[Y_{n-i}])
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Now we expand the last summation as&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
(E[Y_0] + E[Y_{n-1}]) + \dots + (E[Y_{n-1}] + E[Y_0]) = 2\sum_{i=0}^{n-1}E[Y_i]
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Thus, we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
E[Y_n] \le \frac{4}{n}\sum_{i=0}^{n-1}E[Y_i]
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;Then, we will show that for all integers &lt;span class="math"&gt;\(n&amp;gt;0\)&lt;/span&gt;, &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
E[Y_n] &amp;amp;\le&amp;amp; \frac{1}{4}\dbinom{n+3}{3} \\
       &amp;amp;=&amp;amp; \frac{1}{4}\cdot\frac{(n+3)(n+2)(n+1)}{6} \\ 
       &amp;amp;=&amp;amp; O(n^3)
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Then, we use &lt;em&gt;Jensen’s inequality&lt;/em&gt;, which states that &lt;span class="math"&gt;\(f(E[X]) \le E[f(X)]\)&lt;/span&gt; provided
the expectations exist and are finite, and f(x) is convex. Let this &lt;span class="math"&gt;\(X\)&lt;/span&gt; be &lt;span class="math"&gt;\(h_n\)&lt;/span&gt; and
&lt;span class="math"&gt;\(f(x) = 2^x\)&lt;/span&gt;, then &lt;span class="math"&gt;\(E[f(X)] = E[Y_n]\)&lt;/span&gt;. So, we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
2^{E[h_n]} \le \frac{1}{4}\dbinom{n+3}{3} = O(n^3)
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;By taking the log of both sides, we have &lt;span class="math"&gt;\(E[h_n] = O(\log n)\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remarks:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let’s first prove &lt;span class="math"&gt;\(\sum_{i=0}^{n-1}\dbinom{i+3}{3} = \dbinom{n+3}{4}\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt; Use &lt;em&gt;Pascal’s identity:&lt;/em&gt; &lt;span class="math"&gt;\(\dbinom{n}{k} = \dbinom{n-1}{k-1} + \dbinom{n-1}{k}\)&lt;/span&gt;
Also using the simple identity &lt;span class="math"&gt;\(\dbinom{4}{4} = 1 = \dbinom{3}{3}\)&lt;/span&gt;. We have:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
\dbinom{n+3}{4} &amp;amp;=&amp;amp; \dbinom{n+2}{3} + \dbinom{n+2}{4} \\
                &amp;amp;=&amp;amp; \dbinom{n+2}{3} + \dbinom{n+1}{3} + \dbinom{n+1}{4} \\
                &amp;amp;=&amp;amp; \dbinom{n+2}{3} + \dbinom{n+!}{3} + \dbinom{n}{3} + \dbinom{n}{4} \\
                &amp;amp;\vdots&amp;amp; \\
                &amp;amp;=&amp;amp; \dbinom{n+2}{3} + \dbinom{n+!}{3} + \dbinom{n}{3} + \dots + \dbinom{4}{3} + \dbinom{4}{4} \\
                &amp;amp;=&amp;amp; \sum_{i=0}^{n-1}\dbinom{i+3}{3}
\end{eqnarray*}
$$&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Let’s prove &lt;span class="math"&gt;\(E[Y_n] \le \frac{1}{4}\dbinom{n+3}{3}\)&lt;/span&gt; by induction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt; &lt;em&gt;Base case:&lt;/em&gt; &lt;span class="math"&gt;\(n=1\)&lt;/span&gt;. &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
1 = Y_1 = E[Y_1] \le \frac{1}{4}\dbinom{1+3}{3} = 1.
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Inductive hypothesis:&lt;/em&gt; Assume that &lt;span class="math"&gt;\(E[Y_i]\le\frac{1}{4}\dbinom{i+3}{3}\)&lt;/span&gt; for all &lt;span class="math"&gt;\(i&amp;lt;n\)&lt;/span&gt;. Then,&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
E[Y_n] &amp;amp;\le&amp;amp; \frac{4}{n}\sum_{i=0}^{n-1}E[Y_i] \\
       &amp;amp;\le&amp;amp; \frac{1}{4}\dbinom{i+3}{3} \\
       &amp;amp;=&amp;amp;   \frac{1}{n}\sum_{i=0}^{n-1}\dbinom{i+3}{3} \\
       &amp;amp;=&amp;amp;   \frac{1}{n}\dbinom{n+3}{4} \\
       &amp;amp;=&amp;amp;   \frac{1}{n}\frac{(n+3)!}{4!(n-1)!} \\
       &amp;amp;=&amp;amp;   \frac{1}{4}\frac{(n+3)!}{3!n!} \\
       &amp;amp;=&amp;amp;   \frac{1}{4}\dbinom{n+3}{3}
\end{eqnarray*}
$$&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;I 
&lt;a href="https://www.cs.bgu.ac.il/~fds112/wiki.files/P05.pdf"&gt;reference this lecture note&lt;/a&gt;
 when I try to develop the proof. 
Overall, I share the similar proof with this one. However, we have slightly 
difference in terms of how we 
define &lt;span class="math"&gt;\(E[Y_n]\)&lt;/span&gt;. The note defines an indicator random variables 
&lt;span class="math"&gt;\(Z_{n,i} = I\{I=i\}\)&lt;/span&gt;, where &lt;span class="math"&gt;\(I=i\)&lt;/span&gt; means we pick &lt;span class="math"&gt;\(i_{th}\)&lt;/span&gt; element as our 
first element inserting into the empty tree. Since, we pick the first insertion 
element equally likely, then &lt;span class="math"&gt;\(P(I=i) = \frac{1}{n}\)&lt;/span&gt;, and thus, &lt;span class="math"&gt;\(E[Z_{n,i}] = \frac{1}{n}\)&lt;/span&gt; by &lt;span class="math"&gt;\(E[I_A] = P(A)\)&lt;/span&gt;. Then, he defines &lt;span class="math"&gt;\(Y_n = \sum_{i=1}^nZ_{n,i} \cdot (2 \cdot max(Y_{i-1}, Y_{n-i}))\)&lt;/span&gt; because only one &lt;span class="math"&gt;\(Z_{n,i}\)&lt;/span&gt; can be &lt;span class="math"&gt;\(1\)&lt;/span&gt; and all others are &lt;span class="math"&gt;\(0\)&lt;/span&gt;. It seems right but when he calculates the &lt;span class="math"&gt;\(E[Y_n]\)&lt;/span&gt;, he states that
&lt;span class="math"&gt;\(Z_{n,i}\)&lt;/span&gt; is independent of &lt;span class="math"&gt;\(Y_{i-1}\)&lt;/span&gt; and &lt;span class="math"&gt;\(Y_{n-i}\)&lt;/span&gt;. However, I don’t think so as 
the height of the tree &lt;span class="math"&gt;\(h_n\)&lt;/span&gt;, which &lt;span class="math"&gt;\(Y_n\)&lt;/span&gt; is constructed from 
depends on which element we pick first. I tend to think about &lt;span class="math"&gt;\(E[Y_n]\)&lt;/span&gt; as 
expectation of the conditional expectation.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id="maw-415"&gt;MAW 4.15&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;a. Give a precise expression for the minimum number of nodes in an AVL tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt;.
b. What is the minimum number of nodes in an AVL tree of height 15? &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The minimum number of nodes in an AVL tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt;, &lt;span class="math"&gt;\(S(H) = S(H-1) + S(H-2) + 1 \quad (H \ge 2)\)&lt;/span&gt; with &lt;span class="math"&gt;\(S(0) = 1\)&lt;/span&gt; and &lt;span class="math"&gt;\(S(1) = 2\)&lt;/span&gt;.
It’s a linear nonhomogeneous recurrence relation with constant coefficients. Let’s first find 
out the general solution for corresponding homogeneous recurrence relation &lt;span class="math"&gt;\(S(H) = S(H-1) + S(H-2)\)&lt;/span&gt; first.
The characteristic equation is &lt;span class="math"&gt;\(x^2 - x - 1 = 0\)&lt;/span&gt; and the roots are &lt;span class="math"&gt;\(\frac{1+\sqrt 5}{2}\)&lt;/span&gt; and &lt;span class="math"&gt;\(\frac{1-\sqrt 5}{2}\)&lt;/span&gt;.
So, we have &lt;span class="math"&gt;\(S(H) = c_1\Big(\frac{1+\sqrt 5}{2}\Big)^H + c_2\Big(\frac{1-\sqrt 5}{2}\Big)^H\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Now, for a particular solution to the recurrence relation, let’s guess &lt;span class="math"&gt;\(S(H) = r \quad \text{for some constant } r\)&lt;/span&gt;.
This solution has to satisfy the recurrence relation as well. Thus, &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation*}
r = r + r + 1
\end{equation*}
$$&lt;/div&gt;
&lt;p&gt;So, we have &lt;span class="math"&gt;\(r = -1\)&lt;/span&gt;. Thus, &lt;span class="math"&gt;\(S(H) = c_1\Big(\frac{1+\sqrt 5}{2}\Big)^H + c_2\Big(\frac{1-\sqrt 5}{2}\Big)^H - 1\)&lt;/span&gt;. We plugin
the initial condition to our general solution to solve for &lt;span class="math"&gt;\(c_1\)&lt;/span&gt; and &lt;span class="math"&gt;\(c_2\)&lt;/span&gt;. We get &lt;span class="math"&gt;\(c_1 = 1 + \frac{2}{\sqrt 5}\)&lt;/span&gt;
and &lt;span class="math"&gt;\(c_2 = 1 - \frac{2}{\sqrt 5}\)&lt;/span&gt;. Thus, we have &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
S(H) = \Big(1 + \frac{2}{\sqrt 5}\Big)\Big(\frac{1+\sqrt 5}{2}\Big)^H + \Big(1 - \frac{2}{\sqrt 5}\Big)\Big(\frac{1-\sqrt 5}{2}\Big)^H - 1 \label{eqn:2}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;Now, let &lt;span class="math"&gt;\(H = 15\)&lt;/span&gt; and we have &lt;span class="math"&gt;\(S(15) = 2583\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Initial condition is for the general solution for the recurrence relation, not 
the homogeneous part. Thus, we cannot use the initial condition immediately when 
we have our homogeneous part done.We need to wait until the whole solution 
(homogeneous part + particular part).&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Remarks:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With \ref{eqn:2}, we can actually get the bound of the height of an AVL tree. &lt;/p&gt;
&lt;p&gt;By \ref{eqn:2}, we see that &lt;span class="math"&gt;\(S(H) \ge \Big(\frac{1+\sqrt 5}{2}\Big)^H\)&lt;/span&gt;. Suppose we have &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes in an AVL 
tree of height &lt;span class="math"&gt;\(H\)&lt;/span&gt;. Then &lt;span class="math"&gt;\(N \ge S(H) \ge \Big(\frac{1+\sqrt 5}{2}\Big)^H\)&lt;/span&gt;. Let &lt;span class="math"&gt;\(\phi = \frac{1+\sqrt 5}{2}\)&lt;/span&gt;, then
we have &lt;span class="math"&gt;\(\log _\phi N \ge H\)&lt;/span&gt;, which is &lt;span class="math"&gt;\(H \le 1.44\log _2 N = O(\log N)\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="maw-416"&gt;MAW 4.16&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Show the result of inserting 2,1,4,5,9,3,6,7 into an initially empty AVL tree.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/graphviz-drawings/maw-4-16.gv"&gt;
&lt;img alt="maw-4-16" class="img-responsive" src="/images/maw-4-16.png" style="width: 700px;"/&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;!--[![maw-4-16](/images/maw-4-16.png)](https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/graphviz-drawings/maw-4-16.gv)--&gt;
&lt;h3 id="maw-417"&gt;MAW 4.17&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Keys &lt;span class="math"&gt;\(1, 2, \dots, 2^k-1\)&lt;/span&gt; are inserted in order into an initially empty AVL tree. Prove that the resulting tree
is perfectly balanced &lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
Let’s use induction on &lt;span class="math"&gt;\(k\)&lt;/span&gt; to prove the following statement:&lt;/p&gt;
&lt;p&gt;The result of inserting any increasing sequence of &lt;span class="math"&gt;\(2^k - 1\)&lt;/span&gt; numbers into an 
  initially empty AVL tree results in a perfectly balanced tree of height 
  &lt;span class="math"&gt;\(k-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Base case:&lt;/em&gt; &lt;span class="math"&gt;\(k = 1\)&lt;/span&gt;. Tree has only one node. This is clearly perfectly balanced.
&lt;em&gt;Inductive hypothesis:&lt;/em&gt; Assume hypothesis is true for &lt;span class="math"&gt;\(k = 1, 2, \dots, h\)&lt;/span&gt;. We want to prove that it is true for &lt;span class="math"&gt;\(k = h + 1\)&lt;/span&gt;, i.e., 
for sequence &lt;span class="math"&gt;\(1, 2, \dots, 2^{h+1}-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;After the first &lt;span class="math"&gt;\(2^h - 1\)&lt;/span&gt; insertions, by the induction hypothesis, the tree is perfectly balanced, with height &lt;span class="math"&gt;\(h-1\)&lt;/span&gt;. &lt;span class="math"&gt;\(2^{h-1}\)&lt;/span&gt; is at the root
(can be observed for &lt;span class="math"&gt;\(1 \ge k \le 3\)&lt;/span&gt; situation, where the roots are &lt;span class="math"&gt;\(1\)&lt;/span&gt;, &lt;span class="math"&gt;\(2\)&lt;/span&gt;, &lt;span class="math"&gt;\(4\)&lt;/span&gt; respectively). The left subtree is a perfectly balanced
tree of height &lt;span class="math"&gt;\(h-2\)&lt;/span&gt;, and the right subtree is a perfectly balanced tree containing the numbers &lt;span class="math"&gt;\(2^{h-1}+1\)&lt;/span&gt; through &lt;span class="math"&gt;\(2^h-1\)&lt;/span&gt;, also of height &lt;span class="math"&gt;\(h-2\)&lt;/span&gt;.
See the following picture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="maw-4-17-1" class="img-responsive" src="/images/maw-4-17-1.PNG" style="height: 400px;"/&gt;&lt;/p&gt;
&lt;p&gt;Each of the next &lt;span class="math"&gt;\(2^{h-1}\)&lt;/span&gt; insertions (&lt;span class="math"&gt;\(2^h\)&lt;/span&gt; through &lt;span class="math"&gt;\(2^h + 2^{h-1} - 1\)&lt;/span&gt;) are inserted into the 
right subtree, and the entire sequence of numbers in the right subtree (now &lt;span class="math"&gt;\(2^{h-1}+1\)&lt;/span&gt; through &lt;span class="math"&gt;\(2^h + 2^{h-1}-1\)&lt;/span&gt;)
were inserted in order and are a sequence of &lt;span class="math"&gt;\(2^h - 1\)&lt;/span&gt; nodes (i.e. &lt;span class="math"&gt;\(2^h + 2^{h-1}-1 - (2^{h-1}+1) + 1 = 2^h -1\)&lt;/span&gt;).
By induction hypothesis, they form a perfectly balanced tree of height &lt;span class="math"&gt;\(h-1\)&lt;/span&gt;. See the following picture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="maw-4-17-2" class="img-responsive" src="/images/maw-4-17-2.PNG" style="height: 400px;"/&gt;&lt;/p&gt;
&lt;p&gt;The next insertion, of the number &lt;span class="math"&gt;\(2^h + 2^{h-1}\)&lt;/span&gt;, imbalances the tree at the root because now the height of the right subtree
is &lt;span class="math"&gt;\(h\)&lt;/span&gt; and the height of the left subtree is &lt;span class="math"&gt;\(h-2\)&lt;/span&gt;. Now, we do a single rotation and form a tree with root &lt;span class="math"&gt;\(2^h\)&lt;/span&gt;, and 
a perfectly balanced left subtree of height &lt;span class="math"&gt;\(h-1\)&lt;/span&gt;. The right subtree consists of a perfectly balanced tree 
(of height &lt;span class="math"&gt;\(h-2\)&lt;/span&gt;), with the new node: &lt;span class="math"&gt;\(2^h + 2^{h-1}\)&lt;/span&gt;. See the following picture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="maw-4-17-3" class="img-responsive" src="/images/maw-4-17-3.PNG" style="height: 400px;"/&gt;&lt;/p&gt;
&lt;p&gt;Thus, the right subtree is as if the numbers &lt;span class="math"&gt;\(2^h+1, \dots, 2^h + 2^{h-1}\)&lt;/span&gt; had been 
inserted in order. We subsequently insert the numbers &lt;span class="math"&gt;\(2^h + 2^{h-1} + 1\)&lt;/span&gt; through
&lt;span class="math"&gt;\(2^{h+1} - 1\)&lt;/span&gt; nodes. In other words, we form the right subtree by inserting the 
numbers &lt;span class="math"&gt;\(2^{h} + 1, \dots, 2^{h+1} - 1\)&lt;/span&gt;, which have &lt;span class="math"&gt;\(2^{h} - 1\)&lt;/span&gt; numbers. Then, by
the inductive hypothesis, these &lt;span class="math"&gt;\(2^{h} - 1\)&lt;/span&gt; insertions form a perfectly balanced
subtree of height &lt;span class="math"&gt;\(h-1\)&lt;/span&gt;. See the following picture:&lt;/p&gt;
&lt;p&gt;&lt;img alt="maw-4-17-4" class="img-responsive" src="/images/maw-4-17-4.PNG" style="height: 400px;"/&gt;&lt;/p&gt;
&lt;p&gt;Since the left and right subtrees are perfectly balanced (height &lt;span class="math"&gt;\(h-1\)&lt;/span&gt;), the whole
tree is perfectly balanced.&lt;/p&gt;
&lt;h3 id="maw-423"&gt;MAW 4.23&lt;/h3&gt;
&lt;p&gt;&lt;img alt="maw-4-23" class="img-responsive" src="/images/maw-4-23.JPG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;h3 id="maw-424"&gt;MAW 4.24&lt;/h3&gt;
&lt;p&gt;&lt;img alt="maw-4-24" class="img-responsive" src="/images/maw-4-24.PNG" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;h3 id="maw-425"&gt;MAW 4.25&lt;/h3&gt;
&lt;p&gt;This problem is solved through brute-force calculation. You can reference the example
from figure 4.46 to figure 4.55. I calculate for internal path length of the 
tree and &lt;code&gt;find(1)&lt;/code&gt;, &lt;code&gt;find(2)&lt;/code&gt;. The answer is slightly off than the solution manual.
May need to double check.&lt;/p&gt;
&lt;p&gt;&lt;img alt="maw-4-26" class="img-responsive" src="/images/maw-4-26.JPG" style="width: 700px; height: 400px;"/&gt;&lt;/p&gt;
&lt;h3 id="maw-426"&gt;MAW 4.26&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;a. Show that if all nodes in a splay tree are accessed in sequential order, 
the resulting tree consists of a chain of left children.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Proof:&lt;/strong&gt;
Let’s prove by induction. Let &lt;span class="math"&gt;\(N\)&lt;/span&gt; denote the number of nodes in a splay tree.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Base case:&lt;/em&gt; When &lt;span class="math"&gt;\(N = 1\)&lt;/span&gt;, the claim holds.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Inductive hypothesis:&lt;/em&gt; all nodes &lt;span class="math"&gt;\(1, \dots, N\)&lt;/span&gt; in a splay tree are accessed in sequential
order, the resulting tree consists of a chain of left children. We want to show that 
this holds for &lt;span class="math"&gt;\(N+1\)&lt;/span&gt;. Once we access first &lt;span class="math"&gt;\(N\)&lt;/span&gt; nodes, there are only one
position for &lt;span class="math"&gt;\(N+1\)&lt;/span&gt; node: the right child of the root. The rest of positions are impossible because if the 
&lt;span class="math"&gt;\(N+1\)&lt;/span&gt; node is the right child of any node between the left most node and the root of the resulting tree,
then by BST, &lt;span class="math"&gt;\(N+1\)&lt;/span&gt; node’s value is smaller than root’s value and bigger than left most node’s value.
This violates the induction hypothesis because we are no longer access a splay tree in sequential order.
Now we simply swap the right child of the root with root and we get a chain of left children. &lt;/p&gt;
&lt;h3 id="maw-443"&gt;MAW 4.43&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;a. Show that via AVL single rotations, any binary search tree &lt;span class="math"&gt;\(T_1\)&lt;/span&gt; can be transformed into another
search tree &lt;span class="math"&gt;\(T_2\)&lt;/span&gt; (with the same keys).
b. Give an algorithm to perform this transformation using &lt;span class="math"&gt;\(O(N\log N)\)&lt;/span&gt; rotations on average.
c. Show that this transformation can be done with &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; rotations, worst-case.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s first work through an example shown in the picture below. We transform the tree in the top-left 
of the picture to the tree in the top-right of the picture through several steps linked by single arrows.&lt;/p&gt;
&lt;p&gt;&lt;img alt="maw-4-43" class="img-responsive" src="/images/maw-4-43.jpg" style="width: 700px;"/&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the strategy here is that we do preorder processing. We compare the root &lt;span class="math"&gt;\(T_1\)&lt;/span&gt; with the root
&lt;span class="math"&gt;\(T_2\)&lt;/span&gt;. If they are equal, then we move on to the left and right subtrees of &lt;span class="math"&gt;\(T_1\)&lt;/span&gt; and do the processing 
recursively. However, if they are not equal, we find the &lt;span class="math"&gt;\(T_2\)&lt;/span&gt;‘s root value &lt;span class="math"&gt;\(x\)&lt;/span&gt; in &lt;span class="math"&gt;\(T_1\)&lt;/span&gt; and rotate it to the
root of &lt;span class="math"&gt;\(T_1\)&lt;/span&gt;. Then, we do the recursive processing for the left and right subtrees of &lt;span class="math"&gt;\(T_1\)&lt;/span&gt;. This algorithm
takes &lt;span class="math"&gt;\(O(N\log N)\)&lt;/span&gt; on average because find &lt;span class="math"&gt;\(x\)&lt;/span&gt; takes &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time and AVL rotations also take &lt;span class="math"&gt;\(O(\log N)\)&lt;/span&gt; time. 
Since we could do &lt;span class="math"&gt;\(N\)&lt;/span&gt; rotations, then the result follows. However, a BST can be degenerated and in that case, we have 
&lt;span class="math"&gt;\(O(N)\)&lt;/span&gt; worst-case. &lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;The solution and corresponding figures are majorly taken from 
&lt;a href="https://cseweb.ucsd.edu/classes/su05/cse100/cse100hw1.pdf"&gt;this link&lt;/a&gt;
with minor wording tweak to allow easy understanding for myself. &lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="trees"></category><category term="proof"></category><category term="math"></category><category term="maw"></category></entry><entry><title>Tree Terminology</title><link href="https://zhu45.org/posts/2017/Jan/24/tree-terminology/" rel="alternate"></link><published>2017-01-24T20:23:00+08:00</published><updated>2017-01-24T20:23:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-24:/posts/2017/Jan/24/tree-terminology/</id><summary type="html">&lt;p class="first last"&gt;Commonly seen tree terminology&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="terminology"&gt;
&lt;h2&gt;Terminology&lt;/h2&gt;
&lt;p&gt;Like "list" in Chapter 3, "Trees" is another type of abstraction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tree&lt;/strong&gt;, &lt;strong&gt;root&lt;/strong&gt;, &lt;strong&gt;edge&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We can define a tree recursively. A tree is a collection of nodes. The collection
can be empty; otherwise, a tree consists of a distinguish node &lt;em&gt;r&lt;/em&gt;, called the
&lt;em&gt;root&lt;/em&gt;, and zero or more nonempty (sub)tress &lt;span class="math"&gt;\(T_1\)&lt;/span&gt;, &lt;span class="math"&gt;\(T_2\)&lt;/span&gt;, ..., &lt;span class="math"&gt;\(T_k\)&lt;/span&gt;,
each of whose roots are connected by a directed &lt;em&gt;edge&lt;/em&gt; from &lt;em&gt;r&lt;/em&gt;.&lt;/p&gt;
&lt;img alt="subtree definition illustration" class="img-responsive" src="/images/subtree.PNG"/&gt;
&lt;p&gt;&lt;strong&gt;child&lt;/strong&gt;, &lt;strong&gt;parent&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The root of each subtree is said to be a &lt;em&gt;child&lt;/em&gt; of &lt;em&gt;r&lt;/em&gt;, and &lt;em&gt;r&lt;/em&gt; is the &lt;em&gt;parent&lt;/em&gt;
of each subtree root.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;leaves&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nodes with no children are known as &lt;em&gt;leaves&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;siblings&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nodes with the same parent are &lt;em&gt;siblings&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;path&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;path&lt;/em&gt; from node &lt;span class="math"&gt;\(n_1\)&lt;/span&gt; to &lt;span class="math"&gt;\(n_k\)&lt;/span&gt; is defined as a sequence of nodes
&lt;span class="math"&gt;\(n_1\)&lt;/span&gt;, &lt;span class="math"&gt;\(n_2\)&lt;/span&gt;, ..., &lt;span class="math"&gt;\(n_k\)&lt;/span&gt; such that &lt;span class="math"&gt;\(n_i\)&lt;/span&gt; is the parent of
&lt;span class="math"&gt;\(n_{i+1}\)&lt;/span&gt; for &lt;span class="math"&gt;\(1&amp;lt;= i &amp;lt; k\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;length&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;length&lt;/em&gt; of this path is the number of edges on the path, namely &lt;span class="math"&gt;\(k-1\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;ul class="last simple"&gt;
&lt;li&gt;There is a path of length zero from every node to itself.&lt;/li&gt;
&lt;li&gt;Notice that in a tree there is exactly one path from the root to each node.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;depth&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For any node &lt;span class="math"&gt;\(n_i\)&lt;/span&gt;, the &lt;em&gt;depth&lt;/em&gt; of &lt;span class="math"&gt;\(n_i\)&lt;/span&gt;, is the length of the unique
path from the root to &lt;span class="math"&gt;\(n_i\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;internal path length&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The sum of the depths of all nodes in a tree is known as the &lt;em&gt;internal path length&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;height&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;height&lt;/em&gt; of &lt;span class="math"&gt;\(n_i\)&lt;/span&gt; is the length of the longest path from &lt;span class="math"&gt;\(n_i\)&lt;/span&gt; to
a leaf. (i.e., the height of a node is the number of edges from the node to the deepest leaf)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ancestor&lt;/strong&gt;, &lt;strong&gt;descendant&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If there is a path from &lt;span class="math"&gt;\(n_1\)&lt;/span&gt; to &lt;span class="math"&gt;\(n_2\)&lt;/span&gt;, then &lt;span class="math"&gt;\(n_1\)&lt;/span&gt; is an &lt;em&gt;ancestor&lt;/em&gt;
of &lt;span class="math"&gt;\(n_2\)&lt;/span&gt; and &lt;span class="math"&gt;\(n_2\)&lt;/span&gt; is a &lt;em&gt;descendant&lt;/em&gt; of &lt;span class="math"&gt;\(n_1\)&lt;/span&gt;. If &lt;span class="math"&gt;\(n_1 \neq n_2\)&lt;/span&gt;,
then &lt;span class="math"&gt;\(n_1\)&lt;/span&gt; is a &lt;em&gt;proper ancestor&lt;/em&gt; of &lt;span class="math"&gt;\(n_2\)&lt;/span&gt; and &lt;span class="math"&gt;\(n_2\)&lt;/span&gt; is a &lt;em&gt;proper descendant&lt;/em&gt; of &lt;span class="math"&gt;\(n_1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;internal node&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;An &lt;em&gt;internal node&lt;/em&gt;  is a node with at least one child. In other words, internal nodes are nodes other than leaves.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;degree&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The total number of children of a node is called as &lt;em&gt;degree&lt;/em&gt; of that node. The highest
degree of a node among all the nodes in a tree is called as &lt;em&gt;degree of tree&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;level&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The root node is said to be at &lt;em&gt;level 0&lt;/em&gt; and the children of root node are at &lt;em&gt;level 1&lt;/em&gt;
and the children of the nodes which are at &lt;em&gt;level 1&lt;/em&gt; will be at &lt;em&gt;level 2&lt;/em&gt; and so on ...
In other words, in a tree each step from top to bottom is called as a &lt;em&gt;level&lt;/em&gt; and the &lt;em&gt;level&lt;/em&gt;
count starts with '0' and incremented by one at each level (step).&lt;/p&gt;
&lt;img alt="tree level illustration" class="img-responsive" src="/images/tree-level.PNG"/&gt;
&lt;p&gt;&lt;strong&gt;predecessor / successor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(X\)&lt;/span&gt; has two children, its predecessor is the maximum value in its left subtree
and its successor the minimum value in its right subtree. It makes sense if we do in-order
traversal of the tree.&lt;/p&gt;
&lt;img alt="predecessor-successor" class="img-responsive" src="/images/pred-succ.PNG" style="width: 700px;"/&gt;&lt;p&gt;&lt;strong&gt;Inorder traversal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Given a tree shown below, the inorder traversal (left, root, right) gives: 4, 2, 5, 1, 3&lt;/p&gt;
&lt;img alt="example tree" class="img-responsive" src="/images/tree12.gif"/&gt;&lt;p&gt;&lt;strong&gt;Preorder traversal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Given the same tree above, the preorder traversal (root, left, right) gives: 1, 2, 4, 5, 3&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Postorder traversal&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Given the same tree above, the postorder traversal (left, right, root) gives: 4, 5, 2, 3, 1&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="some-properties"&gt;
&lt;h2&gt;Some properties&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A tree is a collection of N nodes, one of which is the root, and N-1 edges.
(since each edge connects some node to its parent, and every node except
the root has one parent.)&lt;/li&gt;
&lt;li&gt;The root is at depth 0.&lt;/li&gt;
&lt;li&gt;All leaves are at height 0.&lt;/li&gt;
&lt;li&gt;The height of a tree is equal to the height of the root.&lt;/li&gt;
&lt;li&gt;The depth of a tree is equal to the depth of the deepest leaf; this is always
equal to the height of the tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="example"&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;Let's work through MAW 4.1, 4.2, and 4.3 to get the tree terminology clear.&lt;/p&gt;
&lt;a class="reference external image-reference" href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/graphviz-drawings/tree-terminology.gv"&gt;&lt;img alt="tree terminology illustration" class="img-responsive" src="/images/tree-terminology.png"/&gt;&lt;/a&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;"A" is the &lt;em&gt;root&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;"G", "H", "I", "L", "M", "K" are the &lt;em&gt;leaves&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;"A":&lt;ul&gt;
&lt;li&gt;&lt;em&gt;children&lt;/em&gt;: "B", "C"&lt;/li&gt;
&lt;li&gt;&lt;em&gt;depth&lt;/em&gt;: 0&lt;/li&gt;
&lt;li&gt;&lt;em&gt;height&lt;/em&gt;: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;"B":&lt;ul&gt;
&lt;li&gt;&lt;em&gt;parent&lt;/em&gt;: "A"&lt;/li&gt;
&lt;li&gt;&lt;em&gt;children&lt;/em&gt;: "D", "E"&lt;/li&gt;
&lt;li&gt;&lt;em&gt;siblings&lt;/em&gt;: "C"&lt;/li&gt;
&lt;li&gt;&lt;em&gt;depth&lt;/em&gt;: 1&lt;/li&gt;
&lt;li&gt;&lt;em&gt;height&lt;/em&gt;: 3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The depth of the tree is 4&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- `Tree - Terminology &lt;http://btechsmartclass.com/DS/U3_T1.html&gt;`_ --&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="trees"></category><category term="maw"></category></entry><entry><title>MAW: Chapter 3 Reflection</title><link href="https://zhu45.org/posts/2017/Jan/23/maw-chapter-3-reflection/" rel="alternate"></link><published>2017-01-23T10:45:00+08:00</published><updated>2017-01-23T10:45:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-23:/posts/2017/Jan/23/maw-chapter-3-reflection/</id><summary type="html">&lt;p class="first last"&gt;An overview summary of MAW Chapter 3&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I finally finish Chapter 3: List, Stacks, and Queues with almost all the problems
solved. It's time to do some summary and reflection.&lt;/p&gt;
&lt;div class="section" id="reflection"&gt;
&lt;h2&gt;Reflection&lt;/h2&gt;
&lt;p&gt;One important philosophy in this chapter is the
separation between the interface exposed to the user and the implementation details behind the scene.
The interface exposed to the user is the Abstract Data Types (ADTs). In this chapter,
the interface in this chapter is "List". However, there are multiple implementations can meet the
requirement of the interface, which are "Array" and "Linked Lists". We can further
categorize "List" interface into different subcategories "Stack", "Queue", "Deque".
In other words, even we talk about "Stack" ADT, "Queue" ADT, and "Deque" ADT, they are
all essentially the "List" but with some restrictions in terms of list operations.
Here is a picture that helps us to understand this concept better:&lt;/p&gt;
&lt;img alt="data structure summarization" class="img-responsive" src="/images/maw-chap3.PNG"/&gt;
&lt;p&gt;In terms of actual implementation, we can get a sense of what's the basic structure that a data structure
should have. Take a linked list implementation of a queue as an example. The key characteristics
of a queue is that it should have a &lt;span class="math"&gt;\(O(1)\)&lt;/span&gt; operation on both enqueue and dequeue. This leads us to
the pointer to pointing both the front and rear of the list. Thus, our queue "queue.h" and "queue.c"
look like respectively:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QueueRecord&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QueueCDT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QueueRecord&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QueueCDT&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;QueueADT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QueueRecord&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;QueueCDT&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Front&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Rear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, our queue pointed by &lt;tt class="docutils literal"&gt;QueueADT&lt;/tt&gt; is defined by two pointers: &lt;tt class="docutils literal"&gt;Front&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;Rear&lt;/tt&gt;.
Then, Those two pointers are pointing to our actual &lt;tt class="docutils literal"&gt;QueueRecord&lt;/tt&gt;, which how we form our linked list implementation.
So, when we implement a data structure, we can take a top-down view by first thinking about
what characterizes our data structure. That's the very important first step we take. Then, we can think
follow the flow naturally by defining what are the required elements to implement those characteristics.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="chapter-structure"&gt;
&lt;h2&gt;Chapter Structure&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Linked List&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Singly Linked List&lt;/li&gt;
&lt;li&gt;Doubly Linked List&lt;/li&gt;
&lt;li&gt;Circular Linked List&lt;/li&gt;
&lt;li&gt;Applications:&lt;ul&gt;
&lt;li&gt;Polynomial ADT&lt;/li&gt;
&lt;li&gt;Raxi Sort&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Stacks&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Linked List implementation&lt;/li&gt;
&lt;li&gt;Array implementation&lt;/li&gt;
&lt;li&gt;Applications:&lt;ul&gt;
&lt;li&gt;Balancing Symbols&lt;/li&gt;
&lt;li&gt;Postfix Expression (Postfix expression evaluation; Infix to Postfix Conversion)&lt;/li&gt;
&lt;li&gt;Function Call Stack&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Queue&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Array implementation&lt;/li&gt;
&lt;li&gt;Linked List implementation&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="notable-questions"&gt;
&lt;h2&gt;Notable Questions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;3.4, 3.5&lt;/p&gt;
&lt;p&gt;implement set operations using "List" interface. Especialy the union one
provides insights on how we can implement addition of polynomials (3.6)
and integer addition (3.9)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.6, 3.7, 3.8, 3.9&lt;/p&gt;
&lt;p&gt;a set of problems relating to Polynomial ADT&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.10, 3.24&lt;/p&gt;
&lt;p&gt;problems to practice recurrence relation. Josephus problem is particular
interesting because it's a good combination of mathematics, algorithm (dynamic programming)
and data structures.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.12, 3.21, 3.23&lt;/p&gt;
&lt;p&gt;commonly-seen interview questions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.13&lt;/p&gt;
&lt;p&gt;require us to actually implement a radix sort in a real problem.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.18&lt;/p&gt;
&lt;p&gt;balancing symbols using Stack. A really cool problem that the end-product
is a tool that you can use in your daily work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.19, 3.20&lt;/p&gt;
&lt;p&gt;Postfix, Infix related problems. Learn about "shunting yard" algorithm
and how left associate operators (i.e +, -) is different from
right associate operators (i.e ^) in terms of implementation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;3.25, 3.26&lt;/p&gt;
&lt;p&gt;Implement Queue and its variation, Deque, using different data structures.
In particular, circular array implementation.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="left-out"&gt;
&lt;h2&gt;Left Out&lt;/h2&gt;
&lt;p&gt;Some material I left out when I work through this chapter:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;function calls as an example of stack (this part is going to be covered from computer system point of view
in the coming posts).&lt;/li&gt;
&lt;li&gt;cursor implementation of linked list (this part is not on the top priority for now).&lt;/li&gt;
&lt;li&gt;3.7.c, 3.14, 3.16, 3.18.a, 3.22.b&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="misc"></category><category term="maw"></category></entry><entry><title>Num of function calls in recursive Fibonacci routine</title><link href="https://zhu45.org/posts/2017/Jan/22/num-of-function-calls-in-recursive-fibonacci-routine/" rel="alternate"></link><published>2017-01-22T23:12:00+08:00</published><updated>2017-01-22T23:12:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-22:/posts/2017/Jan/22/num-of-function-calls-in-recursive-fibonacci-routine/</id><summary type="html">&lt;p&gt;Origin from MAW 3.24&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is MAW 3.24: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If the recursive rotuine in Section 2.4 used to computeFibonacci numbers is run for N = 50, is stack space likely to run out?Why or why not?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;long&lt;/span&gt;
&lt;span class="nv"&gt;Fib&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
{
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Fib&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Fib&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;N&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s first do an empirical experimentation. By running &lt;a href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/numCalls/numCalls.c"&gt;our test program numCalls&lt;/a&gt;
and we can get the following output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    i               Fib(i)          numCalls
    i = 0           1               1
    i = 1           1               1
    i = 2           2               3
    i = 3           3               5
    i = 4           5               9
    i = 5           8               15
    i = 6           13              25
    i = 7           21              41
    i = 8           34              67
    i = 9           55              109
    i = 10          89              177
    i = 11          144             287
    i = 12          233             465
    i = 13          377             753
    i = 14          610             1219
    i = 15          987             1973
    i = 16          1597            3193
    i = 17          2584            5167
    i = 18          4181            8361
    i = 19          6765            13529
    ... snip ...
    i = 50          20365011074     40730022147
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We know that the Fibonacci numbers are defined by the following recurrence relation:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
F(n) = F(n-1) + F(n-2), \text{ for }n = 2, 3, ... \label{eq:1}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;We define &lt;span class="math"&gt;\(F(0) = F(1) = 1\)&lt;/span&gt;. Now, we want to find out the number of recursive calls made to calculate &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt;. We use &lt;span class="math"&gt;\(G(n)\)&lt;/span&gt; to denote the number of calls made by the recursive program in calculating &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt;. Let’s examine the output above. We see that &lt;span class="math"&gt;\(G(0) = G(1) = 1\)&lt;/span&gt; and to compute &lt;span class="math"&gt;\(G(n)\)&lt;/span&gt; for arbitrary &lt;span class="math"&gt;\(n\)&lt;/span&gt;, we’ll make an initial call, and then &lt;span class="math"&gt;\(G(n-1)\)&lt;/span&gt; calls to calculate &lt;span class="math"&gt;\(F(n-1)\)&lt;/span&gt; and &lt;span class="math"&gt;\(G(n-2)\)&lt;/span&gt; calls to calculate &lt;span class="math"&gt;\(F(n-2)\)&lt;/span&gt;. Thus, we have the following recurrence relation for &lt;span class="math"&gt;\(G(n)\)&lt;/span&gt;:
&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
G(n) = G(n-1) + G(n-2) + 1 \label{eq:2}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;
Let’s solve this recurrence relation by establish the relationship between &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt; and &lt;span class="math"&gt;\(G(n)\)&lt;/span&gt; and then, we can get the closed form based upon the closed form of &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;Let’s suppose that &lt;span class="math"&gt;\(G(n)\)&lt;/span&gt; depends on &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt; in some way. In other words, &lt;span class="math"&gt;\(G(n)\)&lt;/span&gt; is a function of &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt;. Let’s try linear form first:
&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
G(n) = a F(n) + b \text{ where a, b are unknown constants}  \label {eq:3}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;
Since we know that &lt;span class="math"&gt;\(G(0) = G(1) = 1​\)&lt;/span&gt; and &lt;span class="math"&gt;\(F(0) = F(1) = 1​\)&lt;/span&gt;, then \ref{eq:3} becomes &lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
G(1)  &amp;amp; = &amp;amp; a F(1) + b \\
1 &amp;amp; = &amp;amp; a + b
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Now let’s plugin \ref{eq:3} into \ref{eq:2} and using the \ref{eq:1} and we have:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{eqnarray*}
G(n) &amp;amp; = &amp;amp; G(n-1) + G(n-2) + 1 \\
a F(n) + b &amp;amp; = &amp;amp; G(n-1) + G(n-2) + 1 \\
a (F(n-1) + F(n-2)) + b &amp;amp; = &amp;amp; G(n-1) + G(n-2) + 1 \\
a (F(n-1) + F(n-2)) + b &amp;amp; = &amp;amp; a F(n-1) + b + a F(n-2)) + b + 1 \\
b &amp;amp; = &amp;amp; -1
\end{eqnarray*}
$$&lt;/div&gt;
&lt;p&gt;Now, our \ref{eq:3} becomes &lt;span class="math"&gt;\(G(n) = 2F(n) - 1\)&lt;/span&gt;. That is, the number of function calls
to calculate a Fibonacci number &lt;span class="math"&gt;\(F(n)\)&lt;/span&gt; is &lt;span class="math"&gt;\(2F(n) - 1\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Then the question asks about “is the stack space likely to run out?”. This actually confuses
me because it seems like the author tries to indicate that there is a relationship between
the number of recursive calls and the actual space the program is going to take in call stack.
I have no clue so far. But, maybe we can find out the space of our &lt;code&gt;Fib&lt;/code&gt; routine
is going to take in call stack and how large the system call stack and we can compare the two
to get some insights.&lt;/p&gt;
&lt;p&gt;We can use &lt;code&gt;ulimit -a&lt;/code&gt; or &lt;code&gt;ulimit -s&lt;/code&gt; to find out the size of stack that system allows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;ulimit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-a
...&lt;span class="w"&gt; &lt;/span&gt;snip&lt;span class="w"&gt; &lt;/span&gt;...
stack&lt;span class="w"&gt; &lt;/span&gt;size&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;kbytes,&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10240&lt;/span&gt;
...&lt;span class="w"&gt; &lt;/span&gt;snip&lt;span class="w"&gt; &lt;/span&gt;...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the default stack size is &lt;code&gt;10 MB&lt;/code&gt;. Let’s see how large space our &lt;code&gt;Fib&lt;/code&gt;
is going to use on stack: as of &lt;code&gt;gcc 4.6&lt;/code&gt;, there is an option &lt;code&gt;-fstack-usage&lt;/code&gt; to allow
us check the function max amount of stack use. &lt;a href="https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html&amp;gt;"&gt;Read more info here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;numCalls.c:17:1:Fib     48      static
numCalls.c:27:1:main    64      static
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, &lt;code&gt;Fib&lt;/code&gt; only uses &lt;code&gt;48 bytes&lt;/code&gt; and it’s quite unlikely to drain out our stack space. 
But, of course, the runing time is another thing. I mean it’s going to be very slow to get the output
for &lt;span class="math"&gt;\(N = 50\)&lt;/span&gt;.&lt;/p&gt;
&lt;h2 id="future-work"&gt;Future work&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://vulms.vu.edu.pk/Courses/CS201/Downloads/p60-robertson.pdf"&gt;This paper&lt;/a&gt; mentions that 
  \ref{eq:1} and \ref{eq:2} with their initial conditions respectively form second-order 
  Discrete Dynamical System (DDS). This offers some more mathematical insights. This actually reminds
  me equation 1.11 in &lt;em&gt;Concrete Mathematics: A Foundation for Computer Science&lt;/em&gt; working on 
  a generalized Josephus problem recurrence relation with a system of three equations and three unknown
  constant coefficients. In fact, this way of solving problem seems anywhere like differential equations,
  calculating moments in statistics, and so on. Quite interesting.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lots of things can be said about call stack. In addition, “determine the amount of stack a program uses” is an interesting
  question that I may dig in the future.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="math"></category><category term="call-stack"></category><category term="recursion"></category><category term="maw"></category></entry><entry><title>Typecasting in C</title><link href="https://zhu45.org/posts/2017/Jan/19/typecasting-in-c/" rel="alternate"></link><published>2017-01-19T00:53:00+08:00</published><updated>2017-01-19T00:53:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-19:/posts/2017/Jan/19/typecasting-in-c/</id><summary type="html">&lt;p class="first last"&gt;A study of typecasting in C&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This post covers the typecasting in C with the aim to get a clear understanding
of the most commonly-seen C manipulation. This writeup is adapted from
"Hacking - the Art of Exploitation".&lt;/p&gt;
&lt;div class="section" id="tl-dr"&gt;
&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Typecasting change a variable into a different type just for that operation.&lt;/li&gt;
&lt;li&gt;Pointer type determines the size of the data it points to. In other words, when you
do pointer arithemetic (i.e &lt;tt class="docutils literal"&gt;+&lt;/tt&gt;), the number of bytes change (i.e increase) in terms of memory
address is determined by the pointer type.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;void&lt;/tt&gt; pointer is a generic pointer and we need to cast them to the proper data type in order to
de-reference it.&lt;/li&gt;
&lt;li&gt;Pointer is merely a memory address. With typecasting, any type with enough size to hold
the memory address can work like a pointer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="details"&gt;
&lt;h2&gt;Details&lt;/h2&gt;
&lt;p&gt;Typecasting is simply a way to temporarily change a variable's data type,
despite how it was originally define. When a variable is typecast into a different type,
the compiler is basically told to treat that variable as if it were the new data type,
but &lt;em&gt;only for that operation&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Typecasting is mostly used with pointers. Before we jump into typecasting, let's take a look
why we need to define type for pointer (pointer is just a memory address). One reason for this
is to try to limit programming errors. An integer pointer should only point to integer data, while
a character pointer should only point to character data. Another reason is for pointer arithmetic.
An integer is four bytes in size, while a character only takes up a single byte.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'e'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[integer pointer] points to %p, which contains the integer %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[char pointer] points to %p, which contains the char '%c'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The program itself is pretty straightforward. Here is the output:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[integer pointer] points to 0x7ffd90db45a4, which contains the integer 1
[integer pointer] points to 0x7ffd90db45a8, which contains the integer 2
[integer pointer] points to 0x7ffd90db45ac, which contains the integer 3
[integer pointer] points to 0x7ffd90db45b0, which contains the integer 4
[integer pointer] points to 0x7ffd90db45b4, which contains the integer 5
[char pointer] points to 0x7ffd90db45c1, which contains the char 'a'
[char pointer] points to 0x7ffd90db45c2, which contains the char 'b'
[char pointer] points to 0x7ffd90db45c3, which contains the char 'c'
[char pointer] points to 0x7ffd90db45c4, which contains the char 'd'
[char pointer] points to 0x7ffd90db45c5, which contains the char 'e'
&lt;/pre&gt;
&lt;p&gt;Even though the same value of 1 is added to &lt;tt class="docutils literal"&gt;int_pointer&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;char_pointer&lt;/tt&gt;
in their respective loops, the compiler increments the pointer's addresses by different
amounts. Since a char is only 1 byte, the pointer to the next char would naturally also be 1 byte over.
But since an integer is 4 bytes, a pointer to the next integer has to be 4 bytes over.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'e'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// The char_pointer and int_pointer now point to incompatible data types.&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[integer pointer] points to %p, which contains the integer %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[char pointer] points to %p, which contains the char '%d'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ gcc pointer_types2.c
pointer_types2.c: In function ‘main’:
pointer_types2.c:13: warning: assignment from incompatible pointer type
pointer_types2.c:14: warning: assignment from incompatible pointer type
&lt;/pre&gt;
&lt;p&gt;Here, the compiler and the programmer are the only ones that care about a pointer's type.
In the compiled code, a pointer is nothing more than a memory address, so the compiler
will still compile the code if a pointer points to an incompatible data type - it simply warns us
to anticipate unexpected results.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[integer pointer] points to 0x7ffe2d481324, which contains the integer a
[integer pointer] points to 0x7ffe2d481328, which contains the integer e
[integer pointer] points to 0x7ffe2d48132c, which contains the integer ▒
[integer pointer] points to 0x7ffe2d481330, which contains the integer
[integer pointer] points to 0x7ffe2d481334, which contains the integer
[char pointer] points to 0x7ffe2d481301, which contains the char '1'
[char pointer] points to 0x7ffe2d481302, which contains the char '0'
[char pointer] points to 0x7ffe2d481303, which contains the char '0'
[char pointer] points to 0x7ffe2d481304, which contains the char '0'
[char pointer] points to 0x7ffe2d481305, which contains the char '2'
&lt;/pre&gt;
&lt;p&gt;Even though &lt;tt class="docutils literal"&gt;int_pointer&lt;/tt&gt; points to character data that only contains 5 bytes of data, it is still
typed as an integer. This means that adding 1 to the pointer will increment the address by 4 each time.
Similarly, the &lt;tt class="docutils literal"&gt;char_pointer&lt;/tt&gt;'s address is only incremented by 1 each time, stepping through the 20 bytes
of integer data, one byte at a time. So, we need to make sure that pointer type is correct. This is the place where
we need typecasting.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'e'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[integer  pointer] points to %p, which contains the integer %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;int_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[char pointer] points to %p, which contains the char '%d'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;char_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Typecasting is just a way to change the type of a variable on the fly. In the above code, when the pointers
are initially set, the data is typecast into the pointer's data type. This will prevent the C compiler from complaining
about the conflicting data types; however, any pointer arithmetic will still be incorrect (because typecasting is just
for that one operation). To fix that, when 1 is added to the pointers, they must first be typecast into the correct data type
so the address is incremented by the correct amount. Then this pointer needs to be typecast back into the pointer's data type
once again. It works but in a not beautiful way.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[integer pointer] points to 0x7ffd484ac470, which contains the integer a
[integer pointer] points to 0x7ffd484ac471, which contains the integer b
[integer pointer] points to 0x7ffd484ac472, which contains the integer c
[integer pointer] points to 0x7ffd484ac473, which contains the integer d
[integer pointer] points to 0x7ffd484ac474, which contains the integer e
[char pointer] points to 0x7ffd484ac450, which contains the char '1'
[char pointer] points to 0x7ffd484ac454, which contains the char '2'
[char pointer] points to 0x7ffd484ac458, which contains the char '3'
[char pointer] points to 0x7ffd484ac45c, which contains the char '4'
[char pointer] points to 0x7ffd484ac460, which contains the char '5'
&lt;/pre&gt;
&lt;p&gt;Sometimes, we probably want to use a generic, typeless pointer. In C, a void pointer is a typeless pointer, defined by the &lt;tt class="docutils literal"&gt;void&lt;/tt&gt; keyword.
Here are two things we need to note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;pointers cannot be de-referenced unless they have a type. In order to retrieve the value stored in the pointer's memory address, the
compiler must first know what type of data it is.&lt;/li&gt;
&lt;li&gt;void pointers must also be typecast before doing pointer arithmetic, which indicates that a void pointer's main purpose is to simply hold a
memory address.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let's rewrite our program.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'e'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[char pointer] points to %p, which contains the char %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[integer pointer] points to %p, which contains the integer %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;void_pointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[char pointer] points to 0x7fff06cf8de0, which contains the char a
[char pointer] points to 0x7fff06cf8de1, which contains the char b
[char pointer] points to 0x7fff06cf8de2, which contains the char c
[char pointer] points to 0x7fff06cf8de3, which contains the char d
[char pointer] points to 0x7fff06cf8de4, which contains the char e
[integer pointer] points to 0x7fff06cf8dc0, which contains the integer 1
[integer pointer] points to 0x7fff06cf8dc4, which contains the integer 2
[integer pointer] points to 0x7fff06cf8dc8, which contains the integer 3
[integer pointer] points to 0x7fff06cf8dcc, which contains the integer 4
[integer pointer] points to 0x7fff06cf8dd0, which contains the integer 5
&lt;/pre&gt;
&lt;p&gt;The void pointer is really just holding the memory addresses, while the hard-coded typecasting
is telling the compiler to use the proper types whenever the pointer is used. Since the type is
taken care of by the typecasts, the void pointer is truly nothin more than a memory address.
With the data types defined by typecasting, anything that is big enough to hold a four-byte or eight-byte value can
work the same way as a void pointer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'e'&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;char_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[hacky_nonpointer] points to %p, which contains the char %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;int_array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[hacky_nonpointer] points to %p, which contains the integer %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hacky_nonpointer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that I use &lt;tt class="docutils literal"&gt;unsigned long int&lt;/tt&gt; because I'm on a 64-bit system. &lt;tt class="docutils literal"&gt;unsigned int&lt;/tt&gt; is enough for 32-bit system.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[hacky_nonpointer] points to 0x7fff3e378360, which contains the char a
[hacky_nonpointer] points to 0x7fff3e378361, which contains the char b
[hacky_nonpointer] points to 0x7fff3e378362, which contains the char c
[hacky_nonpointer] points to 0x7fff3e378363, which contains the char d
[hacky_nonpointer] points to 0x7fff3e378364, which contains the char e
[hacky_nonpointer] points to 0x7fff3e378340, which contains the integer 1
[hacky_nonpointer] points to 0x7fff3e378344, which contains the integer 2
[hacky_nonpointer] points to 0x7fff3e378348, which contains the integer 3
[hacky_nonpointer] points to 0x7fff3e37834c, which contains the integer 4
[hacky_nonpointer] points to 0x7fff3e378350, which contains the integer 5
&lt;/pre&gt;
&lt;p&gt;The important thing to remember about variables in C is that the compiler is the
only thing that care about a variable's type. In the end, after the program has been compiled,
the variables are nothing more than memory addresses. This means that variables of one type can easily be coerced into
behaving like another type by telling the compiler to typecast them into the desired type.&lt;/p&gt;
&lt;/div&gt;
</content><category term="programming languages"></category><category term="c"></category><category term="pointer"></category></entry><entry><title>Difference between i++ and ++i</title><link href="https://zhu45.org/posts/2017/Jan/11/difference-between-i-and-i/" rel="alternate"></link><published>2017-01-11T22:39:00+08:00</published><updated>2017-01-11T22:39:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-11:/posts/2017/Jan/11/difference-between-i-and-i/</id><summary type="html">&lt;p class="first last"&gt;Understanding easily confused part of C&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I'm starting to read through &lt;a class="reference external" href="https://www.amazon.com/Hacking-Art-Exploitation-Jon-Erickson/dp/1593271441"&gt;Hacking: The Art of Exploitation&lt;/a&gt; on
my four hours daily commute to work in order to get myself more comfortable working with C. I resolve a puzzle I have about C, as shown in the title.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;i++&lt;/tt&gt; means increment the value of &lt;tt class="docutils literal"&gt;i&lt;/tt&gt; by &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; &lt;em&gt;after&lt;/em&gt; evaluating the arithmetic operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;b&lt;/tt&gt; will contain &lt;tt class="docutils literal"&gt;30&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;a&lt;/tt&gt; will contain &lt;tt class="docutils literal"&gt;6&lt;/tt&gt;, since the shorthand of &lt;tt class="docutils literal"&gt;b = a++ * 6&lt;/tt&gt;;
is the equivalent to the following statements:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;++i&lt;/tt&gt; means increment the value of &lt;tt class="docutils literal"&gt;i&lt;/tt&gt; by &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; &lt;em&gt;before&lt;/em&gt; evaluating the arithmetic operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;b&lt;/tt&gt; will contain &lt;tt class="docutils literal"&gt;36&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;a&lt;/tt&gt; wil contain &lt;tt class="docutils literal"&gt;6&lt;/tt&gt;, since the shorthand of &lt;tt class="docutils literal"&gt;b = ++a * 6&lt;/tt&gt;; is the
equivalent to the following statement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In fact, the two principles mentioned above apply more than "evaluating the arithmetic operation".
For example, in the stack &lt;tt class="docutils literal"&gt;push&lt;/tt&gt; operation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/* Push an element on the Stack&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isFull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;resizeStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;we can do &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;S-&amp;gt;Array[++S-&amp;gt;TopOfStack]&lt;/span&gt; = elem;&lt;/tt&gt;, which is equivalent with the following, a nice short verison:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another example is stack &lt;tt class="docutils literal"&gt;topAndPop&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/* Check the top element and pop it out of Stack&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="n"&gt;ET&lt;/span&gt;
&lt;span class="nf"&gt;topAndPop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this case, we essentially do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TopOfStack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Look how clean I can make my code is if I can understand the difference between &lt;tt class="docutils literal"&gt;++i&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;i++&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;--- 01/19/2017 UPDATE ---&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;++i&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;i++&lt;/tt&gt; is really a powerful technique to shorten the C code. However, it can be error-prune
if we are not careful enough.&lt;/p&gt;
&lt;p&gt;Let's take a look at the following code snippet, which is adapted from the program on K &amp;amp; R p.117.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*++&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*++&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'x'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user invokes the program with -x option&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'n'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user invokes the program with -n option&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"illegal option %c&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usage: find -x pattern&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This program itself is straightforward. Let's take a look at &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(*++argv)[0]&lt;/span&gt;&lt;/tt&gt; to see what it means.
Since &lt;tt class="docutils literal"&gt;argv&lt;/tt&gt; is a pointer to the beginning of the array of argument strings, incrementing it by
&lt;tt class="docutils literal"&gt;1&lt;/tt&gt; (i.e. &lt;tt class="docutils literal"&gt;++argv&lt;/tt&gt;) makes it point at the original &lt;tt class="docutils literal"&gt;argv[1]&lt;/tt&gt; instead of &lt;tt class="docutils literal"&gt;argv[0]&lt;/tt&gt;. Then we
dereference it to get the value of the argument string that we are currently looking at (i.e
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;*++argv&lt;/span&gt;&lt;/tt&gt;). Now, we get its first character by adding &lt;tt class="docutils literal"&gt;[0]&lt;/tt&gt;. So, we have &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(*++argv)[0]&lt;/span&gt;&lt;/tt&gt;.
For example, we run our program with &lt;tt class="docutils literal"&gt;a.out &lt;span class="pre"&gt;-x&lt;/span&gt; &lt;span class="pre"&gt;-n&lt;/span&gt; pattern&lt;/tt&gt;. Then our &lt;tt class="docutils literal"&gt;argv&lt;/tt&gt; looks like
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;{"-x",&lt;/span&gt; &lt;span class="pre"&gt;"-n",&lt;/span&gt; "pattern"}&lt;/tt&gt;. Then &lt;tt class="docutils literal"&gt;argv[0]&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;"-x"&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;argv[1]&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;"-n"&lt;/span&gt;&lt;/tt&gt;, and so on.&lt;/p&gt;
&lt;p&gt;The reason we need parenthesis in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(*++argv)[0]&lt;/span&gt;&lt;/tt&gt; can be seen in the next line &lt;tt class="docutils literal"&gt;c = &lt;span class="pre"&gt;*++argv[0]&lt;/span&gt;&lt;/tt&gt;.
Since &lt;tt class="docutils literal"&gt;[]&lt;/tt&gt; binds tighter than &lt;tt class="docutils literal"&gt;*&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;++&lt;/tt&gt;, then &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;*++argv[0]&lt;/span&gt;&lt;/tt&gt; is equivalent with
&lt;tt class="docutils literal"&gt;c = &lt;span class="pre"&gt;*++(argv[0])&lt;/span&gt;&lt;/tt&gt;. &lt;tt class="docutils literal"&gt;argv[0]&lt;/tt&gt; points to the first char of the argument string that &lt;tt class="docutils literal"&gt;argv&lt;/tt&gt; pointing
at. Then we increment and dereference &lt;tt class="docutils literal"&gt;argv[0]&lt;/tt&gt; to get the next character in the argument string.
For instance, suppose &lt;tt class="docutils literal"&gt;argv&lt;/tt&gt; pointing at &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-x&lt;/span&gt;&lt;/tt&gt;. Then &lt;tt class="docutils literal"&gt;argv[0]&lt;/tt&gt; pointing at &lt;tt class="docutils literal"&gt;-&lt;/tt&gt; and we increment and
dereference &lt;tt class="docutils literal"&gt;argv[0]&lt;/tt&gt; to get &lt;tt class="docutils literal"&gt;x&lt;/tt&gt; and assign to &lt;tt class="docutils literal"&gt;c&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;We can see that the level of precedence of operators is crtical in this case. This can be seen from table on
p.53. in K &amp;amp; R:&lt;/p&gt;
&lt;img alt="precedence of operators in C" class="img-responsive" src="/images/precedence-operators-c.PNG"/&gt;
&lt;p&gt;Let's see another example from K &amp;amp; R p. 105.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;strcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this case, the value of &lt;tt class="docutils literal"&gt;*t++&lt;/tt&gt; is the character that &lt;tt class="docutils literal"&gt;t&lt;/tt&gt; pointed to before &lt;tt class="docutils literal"&gt;t&lt;/tt&gt; was incremented; the
postfix &lt;tt class="docutils literal"&gt;++&lt;/tt&gt; doesn't change &lt;tt class="docutils literal"&gt;t&lt;/tt&gt; until after this character has been fetched. This makes sense if we
consider it from precedence of the operators' view. &lt;tt class="docutils literal"&gt;*&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;++&lt;/tt&gt; have the same precedence in our table. Thus,
we evaluate the expression in ordinary order: from left to right. We first evaluate &lt;tt class="docutils literal"&gt;*s&lt;/tt&gt; then we increment &lt;tt class="docutils literal"&gt;s&lt;/tt&gt;.&lt;/p&gt;
</content><category term="programming languages"></category><category term="c"></category></entry><entry><title>Modify array inside function in C</title><link href="https://zhu45.org/posts/2017/Jan/08/modify-array-inside-function-in-c/" rel="alternate"></link><published>2017-01-08T09:23:00+08:00</published><updated>2017-01-08T09:23:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-08:/posts/2017/Jan/08/modify-array-inside-function-in-c/</id><summary type="html">&lt;p class="first last"&gt;Commonly seen C usage&lt;/p&gt;
</summary><content type="html">&lt;p&gt;In this post, I want to write down the lesson learned
about modifying array inside a function in C with an example
from MAW 3.15.a:&lt;/p&gt;
&lt;blockquote&gt;
Write an array implementation of self-adjusting lists.
A self-adjusting list is like a regular list, except that
all insertions are performed at the front, and when an element
is accessed by a Find, it is moved to the front of the list
without changing the relative order of the other items.&lt;/blockquote&gt;
&lt;p&gt;In general, there are two cases when we need to use functions to work with array. Let's
examine accordingly.&lt;/p&gt;
&lt;div class="section" id="modify-the-array-content"&gt;
&lt;h2&gt;Modify the array content&lt;/h2&gt;
&lt;p&gt;Let's take a look at the following sample function first:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;change&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"array address inside function: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and in our test function we do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_change&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"before change, test address: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"after change, test address: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The output looks something like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Before:1 2 3
before change, test address: 0x7fffffffe050
array address inside function: 0x7fffffffe050
After:5 5 5
after change, test address: 0x7fffffffe050
&lt;/pre&gt;
&lt;p&gt;Let's examine our &lt;tt class="docutils literal"&gt;change&lt;/tt&gt; function under gdb.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
p array
$1 = (int *) 0x7fffffffe050
&lt;/pre&gt;
&lt;p&gt;shows us that actually &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; is a pointer to int with the address &lt;tt class="docutils literal"&gt;0x7fffffffe050&lt;/tt&gt;.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(gdb) p *0x7fffffffe050
$3 = 1
&lt;/pre&gt;
&lt;p&gt;If we take a look at what value hold the address, we can see that it's &lt;tt class="docutils literal"&gt;1&lt;/tt&gt;, which is the first element of
our &lt;tt class="docutils literal"&gt;int test[3]&lt;/tt&gt; array. This leads to our very first important observation:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;When pass an array to a function, it will decay to a pointer pointing to the first element of the array.
In other words, we can do &lt;tt class="docutils literal"&gt;p *array&lt;/tt&gt; in gdb and get &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since the size of int under my system is 4 bytes (check by &lt;tt class="docutils literal"&gt;p sizeof(int)&lt;/tt&gt; in gdb), and let's examine the four conseuctive
bytes with starting address &lt;tt class="docutils literal"&gt;0x7fffffffe050&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(gdb) x/4bx array
0x7fffffffe050: 0x01    0x00    0x00    0x00
&lt;/pre&gt;
&lt;p&gt;As you can see, this is integer &lt;tt class="docutils literal"&gt;1&lt;/tt&gt;. Now, let's start with the first iteration of the loop in &lt;tt class="docutils literal"&gt;change&lt;/tt&gt;. Once we finish the
iteration, &lt;tt class="docutils literal"&gt;i&lt;/tt&gt; becomes &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; and let's see what change to our &lt;tt class="docutils literal"&gt;array&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(gdb) p array[0]
$12 = 5

(gdb) p array
$13 = (int *) 0x7fffffffe050

(gdb) p *0x7fffffffe050
$10 = 5

(gdb) x/4bx array
0x7fffffffe050: 0x05    0x00    0x00    0x00
&lt;/pre&gt;
&lt;p&gt;We can see that the first element of our &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; array becomes &lt;tt class="docutils literal"&gt;5&lt;/tt&gt; and the starting address of our
&lt;tt class="docutils literal"&gt;array&lt;/tt&gt; is still &lt;tt class="docutils literal"&gt;0x7fffffffe050&lt;/tt&gt;. In other words, the only thing changed is the value that
address &lt;tt class="docutils literal"&gt;0x7fffffffe050&lt;/tt&gt; holds. In addition, if you take a look at the array address output, you can see
that before the function call, during the function call, and after the function call, the array address
doesn't change at all: &lt;tt class="docutils literal"&gt;0x7fffffffe050&lt;/tt&gt;. This leads to our second observation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;We can change the &lt;strong&gt;contents&lt;/strong&gt; of array in the caller function (i.e. &lt;tt class="docutils literal"&gt;test_change()&lt;/tt&gt;) through callee function (i.e. &lt;tt class="docutils literal"&gt;change&lt;/tt&gt;)
by passing the the value of array to the function (i.e. &lt;tt class="docutils literal"&gt;int *array&lt;/tt&gt;). This modification can be effective in the
caller function without any &lt;tt class="docutils literal"&gt;return&lt;/tt&gt; statement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;However, doing so, we doesn't change the address of the array. It seems that array is a local variable inside both caller function
and callee function. Its address is copied and passed from &lt;tt class="docutils literal"&gt;test_change&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;change&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Inside change:

                 +---+---+--+
array -----&amp;gt;  -&amp;gt; | 1 | 2 | 3|
             /-&amp;gt; +---+---+--+
test --------
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's verify above observation with another function &lt;tt class="docutils literal"&gt;change2&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"array address inside function: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With the similar test program &lt;tt class="docutils literal"&gt;test_change2()&lt;/tt&gt; we get the following output:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
TEST: change2
Before:1 2 3
before change, test address: 0x7ffda5b41bc0
array address inside function: 0x7ffda5b41bc0
After:1 2 3
after change, test address: 0x7ffda5b41bc0
&lt;/pre&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;change2&lt;/tt&gt; is very tempting because we assign &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; points to &lt;tt class="docutils literal"&gt;tmp&lt;/tt&gt;, which let &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; inside &lt;tt class="docutils literal"&gt;test_change2&lt;/tt&gt; points to &lt;tt class="docutils literal"&gt;tmp&lt;/tt&gt; as well. However, this is wrong and
the output confirms our observation above: array is local variable to the caller function and callee function, and when we pass a array into a function, the address is
passed (copied) from caller to callee. After that, address inside callee can reassign and will have no effect on the array (address) in caller. In other words, even though
the address inside &lt;tt class="docutils literal"&gt;change2&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;test_change2&lt;/tt&gt; are the same, but they are independent with each other:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
after change2:

                 +---+---+--+
test  ---------&amp;gt; | 1 | 2 | 3|
                 +---+---+--+

                 +---+---+--+
tmp   -----&amp;gt;  -&amp;gt; | 5 | 5 | 5|
             /-&amp;gt; +---+---+--+
array -------
&lt;/pre&gt;
&lt;p&gt;What if we want to modify &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; itself inside &lt;tt class="docutils literal"&gt;test_change2&lt;/tt&gt; beyond the content of the array. What if we want to resize the array to make it hold more values?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="modify-the-array-itself"&gt;
&lt;h2&gt;Modify the array itself&lt;/h2&gt;
&lt;p&gt;Before we start to answer the above question. Let me clear out an important concept: "array on stack" and "array on heap".&lt;/p&gt;
&lt;p&gt;"array on Stack" with the declaration looks like &lt;tt class="docutils literal"&gt;int test[3] = {1,2,3}&lt;/tt&gt; in our test routines. The array declared like this stays on the stack and local to the
function calls. "array on heap" is the dynamic array involving &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt;, which I mention in the &lt;a class="reference external" href="https://zhu45.org/posts/2017/Jan/06/josephus-problem-radix-sort-reflection/"&gt;previous post&lt;/a&gt;. When we talk about
resize the array, we mean the latter case. In other words, we can only change the array itself (number of elements) with dynamically allocated array in the heap.&lt;/p&gt;
&lt;p&gt;Let's take a look at &lt;tt class="docutils literal"&gt;change3&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;change3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and our corresponding test routine &lt;tt class="docutils literal"&gt;test_change3()&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;test_change3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TEST: change3&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"before change, test address: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;change3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After:"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"after change, test address: %p&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first task is to understand &lt;tt class="docutils literal"&gt;int **array&lt;/tt&gt;. There is a template sentence when comes to C type declaration: "&amp;lt;VariableName&amp;gt; is ... &amp;lt;typeName&amp;gt;". In our case,
The template sentence becomes "array is ... int". Now let's work out the "..." with "right-left" rule:&lt;/p&gt;
&lt;blockquote&gt;
"go right when you can, go left when you must"&lt;/blockquote&gt;
&lt;p&gt;In our case, we start with "array" and go right, and nothing left with declaraiton. So, we must go left. the first symbol is &lt;tt class="docutils literal"&gt;*&lt;/tt&gt;, which reads as "pointer to".
So now our template sentence becomes "array is pointer to ... int". Great! Let's continue to go left, we see another &lt;tt class="docutils literal"&gt;*&lt;/tt&gt;, which makes our sentence becomes
"array is pointer to pointer to ... int". Then we meet &lt;tt class="docutils literal"&gt;int&lt;/tt&gt;, which means all the symbol in the declaration is consumed and our sentence is complete:
"array is pointer to pointer to int". This means &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; variable itself is a pointer containing an address of a pointer, which holds an address of a int.&lt;/p&gt;
&lt;p&gt;Let's see if this is true with gdb.:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(gdb) p array
$1 = (int **) 0x7fffffffe070

(gdb) p/a *0x7fffffffe070
$8 = 0x601010

(gdb) p *0x601010
$7 = 1

(gdb) p *array
$2 = (int *) 0x601010

(gdb) p **array
$3 = 1
&lt;/pre&gt;
&lt;p&gt;The address holds by &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;0x7fffffffe070&lt;/tt&gt;. We further examine the value holds by &lt;tt class="docutils literal"&gt;0x7fffffffe070&lt;/tt&gt; and by our assumption, it should be another address
and it is: &lt;tt class="docutils literal"&gt;0x601010&lt;/tt&gt;. Then, we check the value hold by that address, which is expected &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; the first element of our &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; array.&lt;/p&gt;
&lt;p&gt;Our goal is to let &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; array in &lt;tt class="docutils literal"&gt;test_change3()&lt;/tt&gt; be &lt;tt class="docutils literal"&gt;5,5,5&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Before change3

                 +---+---+--+
test  ---------&amp;gt; | 1 | 2 | 3|
                 +---+---+--+

                 +---+---+--+
tmp   ---------&amp;gt; | 5 | 5 | 5|
                 +---+---+--+


After change3

                       +---+---+--+
tmp   ---------------&amp;gt; | 5 | 5 | 5|
                   /-&amp;gt; +---+---+--+
test(array) -------
&lt;/pre&gt;
&lt;p&gt;From the picture we can see that we want to modify &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; inside &lt;tt class="docutils literal"&gt;change3&lt;/tt&gt; pointing to &lt;tt class="docutils literal"&gt;5,5,5&lt;/tt&gt; and this change will persist to the &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; array in our caller function.
In other words, we want both &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; no longer independent but want them "tie up" as the same pointer with different names. How do we do that?&lt;/p&gt;
&lt;p&gt;The solution is given by &lt;tt class="docutils literal"&gt;change3&lt;/tt&gt; but we really need to think about why it makes sense. Firstly, we want to use gdb to examine the address
of key variables:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(gdb) p array
$4 = (int **) 0x7fffffffe070
(gdb) p *array
$5 = (int *) 0x601010
(gdb) p (*array)+1
$14 = (int *) 0x601014
(gdb) p (*array)+2
$15 = (int *) 0x601018
(gdb) p *(*array)
$18 = 1
(gdb) p *(*array)+1
$16 = 2
(gdb) p *(*array)+2
$17 = 3

(gdb) p tmp
$7 = (int *) 0x601030
(gdb) p tmp+1
$8 = (int *) 0x601034
(gdb) p tmp+2
$9 = (int *) 0x601038
(gdb) p *tmp
$10 = 5
(gdb) p *(tmp+1)
$11 = 5
(gdb) p *(tmp+2)
$12 = 5
&lt;/pre&gt;
&lt;p&gt;We first print out the &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; address of each element and we print out the &lt;tt class="docutils literal"&gt;tmp&lt;/tt&gt; address of each element.
With the information above, let's compose our conceptual picture:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Before *array = tmp;

   4 bytes                                         4 bytes
+-----------+-----------+----------+------------+-----------+----------+--------+-------+----------+------
|  1        | 2         | 3        |   ...      |    5      |     5    |  5     |  ...  | 0x601010 | ...
+-----------+-----------+----------+------------+-----------+----------+--------+-------+----------+------
^           ^           ^                       ^           ^          ^                ^
0x601010   0x601014     0x601018                0x601030    0x601034   0x601048         0x7fffffffe070
                                                tmp                                     array
&lt;/pre&gt;
&lt;p&gt;Now, let's execute &lt;tt class="docutils literal"&gt;*array = tmp&lt;/tt&gt;, we get the following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(gdb) p *array
$19 = (int *) 0x601010
(gdb) p *array
$20 = (int *) 0x601030
&lt;/pre&gt;
&lt;p&gt;Now the picture looks like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
After *array = tmp;

   4 bytes                                         4 bytes
+-----------+-----------+----------+------------+-----------+----------+--------+-------+----------+------
|  1        | 2         | 3        |   ...      |    5      |     5    |  5     |  ...  | 0x601030 | ...
+-----------+-----------+----------+------------+-----------+----------+--------+-------+----------+------
^           ^           ^                       ^           ^          ^                ^
0x601010   0x601014     0x601018               0x601030    0x601034   0x601048        0x7fffffffe070
                                               tmp                                    array
&lt;/pre&gt;
&lt;p&gt;We don't modify the address of the &lt;tt class="docutils literal"&gt;array&lt;/tt&gt; itself (still &lt;tt class="docutils literal"&gt;0x7fffffffe070&lt;/tt&gt;) but the content that stored at &lt;tt class="docutils literal"&gt;0x7fffffffe070&lt;/tt&gt;
which is no longer &lt;tt class="docutils literal"&gt;0x601010&lt;/tt&gt; but &lt;tt class="docutils literal"&gt;0x601030&lt;/tt&gt;, which is the starting address of the &lt;tt class="docutils literal"&gt;tmp&lt;/tt&gt;: &lt;tt class="docutils literal"&gt;5,5,5&lt;/tt&gt;.
This may seem like magic. However, in C, a variable (i.e. &lt;tt class="docutils literal"&gt;test&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;test_change3()&lt;/tt&gt;) is merely a synonym for address.
by invoking &lt;tt class="docutils literal"&gt;change3&lt;/tt&gt; through &lt;tt class="docutils literal"&gt;&amp;amp;test&lt;/tt&gt;, we pass in the address &lt;tt class="docutils literal"&gt;0x601010&lt;/tt&gt; via a carrier &lt;tt class="docutils literal"&gt;0x7fffffffe070&lt;/tt&gt;, and we modify the
address to &lt;tt class="docutils literal"&gt;0x601030&lt;/tt&gt; and send the address back again through carrier.&lt;/p&gt;
&lt;p&gt;With this understanding, we can see why the output looks like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
TEST: change3
Before:1 2 3
before change, test address: 0x601010
After:5 5 5
after change, test address: 0x601030
&lt;/pre&gt;
&lt;p&gt;Hoepfully, after our examination, we can understand &lt;tt class="docutils literal"&gt;arrayInsert&lt;/tt&gt; for MAW 3.15.a proposed at the beginning of the post:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;arrayInsert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;realloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/xxks-kkk/Code-for-blog/blob/master/2017/array-to-function/array-to-function.c"&gt;Get the complete source code&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="reference"&gt;
&lt;h2&gt;Reference&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;If you would like to read more about decoding C type declarations. You can read more here:&lt;ul&gt;
&lt;li&gt;&lt;a class="reference external" href="http://unixwiz.net/techtips/reading-cdecl.html"&gt;Reading C type declarations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html"&gt;Right-left rule to understand C type declaration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chapter 3 in "Expert C Programming" by Peter Van Der Linden&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;!-- http://stackoverflow.com/questions/34844003/changing-array-inside-function-in-c --&gt;
&lt;/div&gt;
</content><category term="programming languages"></category><category term="c"></category></entry><entry><title>Josephus Problem &amp; Radix Sort Reflection</title><link href="https://zhu45.org/posts/2017/Jan/06/josephus-problem-radix-sort-reflection/" rel="alternate"></link><published>2017-01-06T00:34:00+08:00</published><updated>2017-01-06T00:34:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2017-01-06:/posts/2017/Jan/06/josephus-problem-radix-sort-reflection/</id><summary type="html">&lt;p class="first last"&gt;Takeaway from MAW 3.13 and 3.10&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This post is a reflection on the two problems (MAW 3.13 &amp;amp; 3.10) I
have been working on for the past five days.&lt;/p&gt;
&lt;div class="section" id="dynamic-arrays-in-c"&gt;
&lt;h2&gt;Dynamic arrays in C&lt;/h2&gt;
&lt;p&gt;One of the ways I try out to solve &lt;a class="reference external" href="https://zhu45.org/posts/2016/Dec/31/josephus-problem/"&gt;Josephus Problem&lt;/a&gt; is to use circular double linked list, which
is implemented in &lt;a class="reference external" href="https://github.com/xxks-kkk/algo/blob/master/linkedList/josephus/circularLinkedList.c"&gt;ET circularDoubleLinkedListJosephus(ET N, ET M)&lt;/a&gt;,
Inside the function, here is what I try to do initially:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I try to make an array of consecutive numbers based upon the input &lt;tt class="docutils literal"&gt;N&lt;/tt&gt;. However, this way doesn't work in C because compiler has no clue
the size of array during compilation phase. This is what people called dynamic array in C. The following two pages offer execellent explanations
to dynamic array specific and array in C in general:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/2-C-adv-data/dyn-array.html"&gt;Dynamic arrays in C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html"&gt;Arrays in C&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is what I've done eventually:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is one thing to note about &lt;tt class="docutils literal"&gt;calloc&lt;/tt&gt;. It essentially the same as &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt; in terms of allocating a chunk of
array. However, unlike &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;calloc&lt;/tt&gt; will zero-initlize the chunk, which is quite useful when we work with
array of integers. In other words, &lt;tt class="docutils literal"&gt;people = &lt;span class="pre"&gt;malloc(N*sizeof(int));&lt;/span&gt;&lt;/tt&gt; is perfectly fine in this case but &lt;tt class="docutils literal"&gt;calloc&lt;/tt&gt;
gives an advantage to have more control on array content, especially useful when we debug.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="circularly-linked-lists"&gt;
&lt;h2&gt;Circularly Linked Lists&lt;/h2&gt;
&lt;p&gt;In MAW, author is kind of in-rush when talks about this section. When comes to implementation, how we deal with header node
need to carefully think through. This is what stated in the book:&lt;/p&gt;
&lt;blockquote&gt;
A popular convention is to have the last cell keep a pointer back to the first. This can be done with or without
a header (if the header is present, the last cell points to it) and can also be done with doubly linked lists (the
first cell's previous pointer points to the last cell).&lt;/blockquote&gt;
&lt;p&gt;Here is my circularly double linked list in picture:&lt;/p&gt;
&lt;img alt="circularly double linked list with dummy node picture" class="img-responsive" src="/images/circularly-double-linked-list-dummy.PNG"/&gt;
&lt;p&gt;In words, our dummy node's &lt;tt class="docutils literal"&gt;Next&lt;/tt&gt; points to the the first data node and &lt;tt class="docutils literal"&gt;Prev&lt;/tt&gt; points to the last data node.
With this setup, the head of the list can be accessed by &lt;tt class="docutils literal"&gt;dummy.Next&lt;/tt&gt; and tail by &lt;tt class="docutils literal"&gt;dummy.Prev&lt;/tt&gt;. In addition,
there will never be &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; pointers in the data structure.&lt;/p&gt;
&lt;!-- http://www.cs.uwm.edu/~cs351/linked-list-variations.pdf --&gt;
&lt;/div&gt;
&lt;div class="section" id="initialize-an-array-of-structs"&gt;
&lt;h2&gt;Initialize an array of structs&lt;/h2&gt;
&lt;p&gt;When implement the radix sort solution, I need to construct an array of buckets,
with each bucket is a single linked list with a dummy node. Here is what I do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="nf"&gt;makeEmptyArrayOfNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numBuckets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Buckets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numBuckets&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numBuckets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Buckets&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Buckets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here are two points worth noting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;tt class="docutils literal"&gt;Pos&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;struct Node*&lt;/tt&gt; (can be checked by &lt;tt class="docutils literal"&gt;ptype&lt;/tt&gt; in GDB) when we allocate
an array of &lt;tt class="docutils literal"&gt;struct Node&lt;/tt&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;There is difference between &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;.&lt;/tt&gt;. In K&amp;amp;R Page 131, it says that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If &lt;tt class="docutils literal"&gt;p&lt;/tt&gt; is a &lt;strong&gt;POINTER&lt;/strong&gt; to a structure, then &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;p-&amp;gt;member-of-structure&lt;/span&gt;&lt;/tt&gt;
refers to the particular member.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and &lt;tt class="docutils literal"&gt;.&lt;/tt&gt; is used to directly access a structure member.
In my case, since &lt;tt class="docutils literal"&gt;Buckets[k]&lt;/tt&gt; with type &lt;tt class="docutils literal"&gt;struct Node&lt;/tt&gt;, then I need to use &lt;tt class="docutils literal"&gt;.&lt;/tt&gt;.
However, if I want to use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt;, I need to use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(&amp;amp;Buckets[k])-&amp;gt;Next&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- http://stackoverflow.com/questions/4173518/c-initialize-array-of-structs --&gt;
&lt;/div&gt;
&lt;div class="section" id="for-loop-instead-of-while"&gt;
&lt;h2&gt;For loop instead of while&lt;/h2&gt;
&lt;p&gt;I try to experiment different trick when I work on my algo. Here is what I try: use &lt;tt class="docutils literal"&gt;for&lt;/tt&gt; loop instead
of &lt;tt class="docutils literal"&gt;while&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;deleteNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;!-- https://www.cs.bu.edu/teaching/ --&gt;
&lt;/div&gt;
&lt;div class="section" id="use-system-implementation-if-find-otherwise-use-my-own-version"&gt;
&lt;h2&gt;Use system implementation if find, otherwise use my own version&lt;/h2&gt;
&lt;p&gt;I'm trying to use &lt;tt class="docutils literal"&gt;fls&lt;/tt&gt; inside &lt;a class="reference external" href="https://github.com/xxks-kkk/algo/blob/77a66a5e911252a93e44bfb6d9bc4c62d85cdffc/linkedList/josephus/nonLinkedListSol.c"&gt;int cyclicShiftJosephus(int N, int M)&lt;/a&gt;,
which return the last (most significant) bit set in value and return the index of that bit.
However, not all system has &lt;tt class="docutils literal"&gt;fls&lt;/tt&gt; shipped by default. So, I implement my own version. But, I would prefer
the program to use system version if it can find one. Otherwise, use mine.&lt;/p&gt;
&lt;p&gt;One solution is to use &lt;tt class="docutils literal"&gt;#ifndef&lt;/tt&gt; with the structure looks like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#ifndef fls&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;#endi&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another solution is to use &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Weak_symbol"&gt;weak symbol&lt;/a&gt;. However, this solution may not be portable.
Then, it looks something like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nf"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;weak&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If system &lt;tt class="docutils literal"&gt;fls&lt;/tt&gt; is defined as strong, my &lt;tt class="docutils literal"&gt;fls&lt;/tt&gt; implementation will be overridden.&lt;/p&gt;
&lt;/div&gt;
</content><category term="programming languages"></category><category term="c"></category><category term="linked-list"></category></entry><entry><title>Josephus problem</title><link href="https://zhu45.org/posts/2016/Dec/31/josephus-problem/" rel="alternate"></link><published>2016-12-31T20:24:00+08:00</published><updated>2016-12-31T20:24:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-31:/posts/2016/Dec/31/josephus-problem/</id><summary type="html">&lt;h2 id="preface"&gt;Preface&lt;/h2&gt;
&lt;p&gt;This is actually MAW 3.10. I gradually realize how dense MAW is.
In the &lt;a href="http://zhu45.org/posts/2016/Dec/26/reflection-on-integer-arithmetic-package-problem/"&gt;previous problem&lt;/a&gt;,
I write almost 500 lines of code. For this one, the problem is not really diffcult to solve if we implement a program 
that follows the game rule exactly. However, I figure …&lt;/p&gt;</summary><content type="html">&lt;h2 id="preface"&gt;Preface&lt;/h2&gt;
&lt;p&gt;This is actually MAW 3.10. I gradually realize how dense MAW is.
In the &lt;a href="http://zhu45.org/posts/2016/Dec/26/reflection-on-integer-arithmetic-package-problem/"&gt;previous problem&lt;/a&gt;,
I write almost 500 lines of code. For this one, the problem is not really diffcult to solve if we implement a program 
that follows the game rule exactly. However, I figure it is a good chance to dig a little deeper to learn somewhat
fully from the question.&lt;/p&gt;
&lt;p&gt;Let’s start to dive in.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;I first describe the &lt;em&gt;Josephus problem&lt;/em&gt; in general. Then, I present a closed form solution to 
solve a special case of the original problem.
Afterwards, I present a recurrence solution to solve the general problem. &lt;/p&gt;
&lt;h2 id="josephus-problem"&gt;Josephus problem&lt;/h2&gt;
&lt;p&gt;The &lt;em&gt;Josephus problem&lt;/em&gt; is the following game: &lt;span class="math"&gt;\(N\)&lt;/span&gt; people, numbered &lt;span class="math"&gt;\(1\)&lt;/span&gt; to &lt;span class="math"&gt;\(N\)&lt;/span&gt;, are
sitting in a circle. Starting at person 1, a hot potato is passed. the &lt;span class="math"&gt;\(M\)&lt;/span&gt;th person 
holding the hot potato is eliminated, the circle closes ranks, and the
game continues with the person who was sitting after the eliminated person picking
up the hot potato. The last remaining person wins. Thus, if &lt;span class="math"&gt;\(M = 1\)&lt;/span&gt; and &lt;span class="math"&gt;\(N = 5\)&lt;/span&gt;, players
are eliminated in order, and player 5 wins. If &lt;span class="math"&gt;\(M = 2\)&lt;/span&gt; and &lt;span class="math"&gt;\(N = 5\)&lt;/span&gt;, the order of elimination
is &lt;span class="math"&gt;\(2\)&lt;/span&gt;,&lt;span class="math"&gt;\(4\)&lt;/span&gt;,&lt;span class="math"&gt;\(1\)&lt;/span&gt;,&lt;span class="math"&gt;\(5\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;You can play with different &lt;span class="math"&gt;\(M\)&lt;/span&gt;, &lt;span class="math"&gt;\(N\)&lt;/span&gt; on this &lt;a href="http://webspace.ship.edu/deensley/mathdl/Joseph.html"&gt;site&lt;/a&gt; to get a better sense of the problem.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;MAW uses a problem description that is slight different than the problem description usually find online. In the book, he defines &lt;span class="math"&gt;\(M\)&lt;/span&gt; in term of number of passes. However, in our problem description, we use &lt;span class="math"&gt;\(M\)&lt;/span&gt; to indicate the &lt;span class="math"&gt;\(M\)&lt;/span&gt;th person get
eliminated. Here is an example to show the difference.In MAW description, &lt;span class="math"&gt;\(M = 0\)&lt;/span&gt; and &lt;span class="math"&gt;\(N = 5\)&lt;/span&gt;, players are eliminated in 
order. However, in our own intepretation, &lt;span class="math"&gt;\(M\)&lt;/span&gt; should be &lt;span class="math"&gt;\(1\)&lt;/span&gt; in order to achieve the same elimination order. Similarly, in 
the book, &lt;span class="math"&gt;\(M = 1\)&lt;/span&gt; when we have &lt;span class="math"&gt;\(2\)&lt;/span&gt;, &lt;span class="math"&gt;\(4\)&lt;/span&gt;, &lt;span class="math"&gt;\(1\)&lt;/span&gt;, &lt;span class="math"&gt;\(5\)&lt;/span&gt; elimination order for the second example.  Mathematically, 
&lt;span class="math"&gt;\(M_{new} = M_{MAW} + 1\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="josephus-problem-with-m-2"&gt;Josephus problem with &lt;span class="math"&gt;\(M = 2\)&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;Let’s first discuss a special case of the Josephus Problem: &lt;span class="math"&gt;\(M = 2\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In the following, &lt;span class="math"&gt;\(n\)&lt;/span&gt; denotes the number of 
people in the initial circle, and &lt;span class="math"&gt;\(m\)&lt;/span&gt; denotes the count for each step. In other words, &lt;span class="math"&gt;\(m-1\)&lt;/span&gt; people
are skipped and the &lt;span class="math"&gt;\(m\)&lt;/span&gt;-th is eliminated. The people in the circle are numbered from &lt;span class="math"&gt;\(1\)&lt;/span&gt; to &lt;span class="math"&gt;\(n\)&lt;/span&gt;. Our goal
is to find &lt;span class="math"&gt;\(J(n,m)\)&lt;/span&gt;, which denotes the survivor’s number (i.e. &lt;span class="math"&gt;\(J(5,1) = 3\)&lt;/span&gt;). For simplicity, let &lt;span class="math"&gt;\(F(n) = J(n,2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="joseph problem" class="img-responsive" src="https://zhu45.org/images/josephus-1.png"/&gt; &lt;/p&gt;
&lt;p&gt;One quick observation is that after the first go-round, we are left with the same problem but for a different
number of people. For instance, when &lt;span class="math"&gt;\(n = 10\)&lt;/span&gt;, after the first go-round, we eliminate &lt;span class="math"&gt;\(2\)&lt;/span&gt;, &lt;span class="math"&gt;\(4\)&lt;/span&gt;, &lt;span class="math"&gt;\(6\)&lt;/span&gt;, &lt;span class="math"&gt;\(8\)&lt;/span&gt;, &lt;span class="math"&gt;\(10\)&lt;/span&gt;
and then we go to the second-round beginning with &lt;span class="math"&gt;\(3\)&lt;/span&gt;, which is the same problem as the original one. 
The only difference is that the person with number &lt;span class="math"&gt;\(3\)&lt;/span&gt; in the first-round now becomes number &lt;span class="math"&gt;\(2\)&lt;/span&gt; in the second-round.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Case 1: When &lt;span class="math"&gt;\(n\)&lt;/span&gt; is even …&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let &lt;span class="math"&gt;\(n = 2k\)&lt;/span&gt;. After the first-round we are left with &lt;span class="math"&gt;\(k\)&lt;/span&gt; people, and we try to find out what is &lt;span class="math"&gt;\(F(k)\)&lt;/span&gt;. In addition, by
our observation, the numbering of people is changed. If &lt;span class="math"&gt;\(3\)&lt;/span&gt; is actually the answer (i.e. &lt;span class="math"&gt;\(F(2k) = 3\)&lt;/span&gt;), then in the second-round
the original person with &lt;span class="math"&gt;\(3\)&lt;/span&gt; now becomes &lt;span class="math"&gt;\(2\)&lt;/span&gt; (i.e. &lt;span class="math"&gt;\(F(k) = 2\)&lt;/span&gt;). So, we have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
F(2k) = 2F(k) - 1, \text{ for } k &amp;gt;= 1 \label{eq:1}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Case 2: When &lt;span class="math"&gt;\(n\)&lt;/span&gt; is odd …&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Let &lt;span class="math"&gt;\(n = 2k+1\)&lt;/span&gt;. By the same reasoning as case 1, after the first-round, we still eliminate &lt;span class="math"&gt;\(k\)&lt;/span&gt; people. For instance, when &lt;span class="math"&gt;\(n = 9\)&lt;/span&gt;,
after the first-round, we elminate &lt;span class="math"&gt;\(2\)&lt;/span&gt;, &lt;span class="math"&gt;\(4\)&lt;/span&gt;, &lt;span class="math"&gt;\(6\)&lt;/span&gt;, &lt;span class="math"&gt;\(8\)&lt;/span&gt;, &lt;span class="math"&gt;\(1\)&lt;/span&gt;. In other words, &lt;span class="math"&gt;\(1\)&lt;/span&gt; is eliminate just after person number &lt;span class="math"&gt;\(2k\)&lt;/span&gt;. So, we 
have&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
F(2k+1) = 2F(k) + 1, \text{ for } k &amp;gt;= 1\label{eq:2}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;So now our goal is to solve the recurrence equations \ref{eq:1} and \ref{eq:2} given &lt;span class="math"&gt;\(F(1) = 1\)&lt;/span&gt; to find a closed form. Let’s do
this by building a table of small values:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| n    | 1 | 2   3 | 4   5   6   7 | 8   9   10   11   12   13   14   15 | 16 |
|------|---|-------|---------------|-------------------------------------|----|
| F(n) | 1 | 1   3 | 1   3   5   7 | 1   3   5    7    9    11   13   15 | 1  |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can group the columns by powers of &lt;span class="math"&gt;\(2\)&lt;/span&gt; (marked by vertical lines in the table); Inside each group,
&lt;span class="math"&gt;\(F(n)\)&lt;/span&gt; is always &lt;span class="math"&gt;\(1\)&lt;/span&gt; at the beginning and then it increases by &lt;span class="math"&gt;\(2\)&lt;/span&gt; until the next group, which is 
the next power of &lt;span class="math"&gt;\(2\)&lt;/span&gt;. So, for every number &lt;span class="math"&gt;\(n\)&lt;/span&gt;, there exists an integer &lt;span class="math"&gt;\(a\)&lt;/span&gt; such that &lt;span class="math"&gt;\(2^a &amp;lt;= n &amp;lt; 2^{a+1}\)&lt;/span&gt;.
For some &lt;span class="math"&gt;\(0 &amp;lt;= l &amp;lt;= 2^a\)&lt;/span&gt;, then &lt;span class="math"&gt;\(n = 2^a + l\)&lt;/span&gt;. In other words, &lt;span class="math"&gt;\(2^a\)&lt;/span&gt; is the largest power of 2 not exceeding &lt;span class="math"&gt;\(n\)&lt;/span&gt;
and &lt;span class="math"&gt;\(l\)&lt;/span&gt; is what’s left. Then, from the table above, we may have the formula:&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
F(n) = F(2^a + l) = 2l + 1 \label{eq:3}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;Now, let’s prove equation \ref{eq:3} by induction on &lt;span class="math"&gt;\(a\)&lt;/span&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Base case.&lt;/em&gt; When &lt;span class="math"&gt;\(a = 0\)&lt;/span&gt;, we must have &lt;span class="math"&gt;\(l = 1\)&lt;/span&gt;; thus we have &lt;span class="math"&gt;\(F(1) = 1\)&lt;/span&gt;, which is true.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Induction.&lt;/em&gt; We use &lt;a href="https://en.wikipedia.org/wiki/Mathematical_induction#Complete_induction"&gt;strong induction&lt;/a&gt; by
assuming that the equation holds for all &lt;span class="math"&gt;\(a\)&lt;/span&gt; up to certain value. Let’s consider this value of &lt;span class="math"&gt;\(a\)&lt;/span&gt;. The induction 
steps has two parts, depending on whether &lt;span class="math"&gt;\(n\)&lt;/span&gt; (and thus &lt;span class="math"&gt;\(l\)&lt;/span&gt;) is even or odd.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(2^a + l = 2k\)&lt;/span&gt;, then&lt;/p&gt;
&lt;p&gt;
&lt;div class="math"&gt;$$
\begin{align*}
F(2^a + l) &amp;amp;= 2F(2^{a-1} + l/2) - 1 &amp;amp;&amp;amp;\text{(by equation 1)} \\
        &amp;amp;= 2(2l/2 + 1) - 1      &amp;amp;&amp;amp;\text{(by induction hypothesis)} \\
        &amp;amp;= 2l + 1
\end{align*}
$$&lt;/div&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If &lt;span class="math"&gt;\(2^a + l = 2k+1\)&lt;/span&gt;, then&lt;/p&gt;
&lt;p&gt;
&lt;div class="math"&gt;$$
\begin{align*}
F(2^a + l) &amp;amp;= 2F(2^{a-1} + (l-1)/2) + 1 &amp;amp;&amp;amp;\text{(by equation 2)} \\
        &amp;amp;= 2(2(l-1)/2 + 1) + 1      &amp;amp;&amp;amp;\text{(by induction hypothesis)} \\
        &amp;amp;= 2l + 1
\end{align*}
$$&lt;/div&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This completes induction step.&lt;/p&gt;
&lt;p&gt;Let’s revisit our closed form solution \ref{eq:3} again. Let’s rewrite it into the form:&lt;/p&gt;
&lt;div class="math"&gt;$$F(n) = 2 (n - 2^a) + 1$$&lt;/div&gt;
&lt;p&gt;&lt;span class="math"&gt;\(n - 2^a\)&lt;/span&gt; is the same as zeroing the most significant bit of &lt;span class="math"&gt;\(n\)&lt;/span&gt;. Then, we multiply the result
with &lt;span class="math"&gt;\(2\)&lt;/span&gt;, which is the same as shifting left one place, and adding &lt;span class="math"&gt;\(1\)&lt;/span&gt; is the same as setting the lowest
bit to &lt;span class="math"&gt;\(1\)&lt;/span&gt;. In other words, equation \ref{eq:3} is essentially do a one-bit cyclic shift left. Let’s try to write this 
out formally. Let &lt;span class="math"&gt;\(n = (b_ab_{a-1}..b_1b_0)_2\)&lt;/span&gt;, then we have:&lt;/p&gt;
&lt;div class="math"&gt;$$ F(n) = F((b_ab_{a-1}..b_1b_0)_2) = (b_{a-1}...b_1b_0b_a)_2 \text{ and } b_a = 1$$&lt;/div&gt;
&lt;p&gt;For a more rigorous derivation of this cyclic shift property, please reference &lt;em&gt;Concrete Mathematics: A Foundation for Computer Science&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The way we solve Josephus problem with &lt;span class="math"&gt;\(M = 2\)&lt;/span&gt; is unlikely to be generalized for arbitrary &lt;span class="math"&gt;\(m\)&lt;/span&gt;. Let’s take &lt;span class="math"&gt;\(n = 10\)&lt;/span&gt;, &lt;span class="math"&gt;\(m = 2\)&lt;/span&gt; example again. The
reason we can derive the nice recurrence equations \ref{eq:1} and \ref{eq:2} is because our observation. Let’s present our
observation is a different way. &lt;span class="math"&gt;\(F(2k)\)&lt;/span&gt; denotes the old numbering before the first-round. &lt;span class="math"&gt;\(F(k)\)&lt;/span&gt; denotes the new numbering 
after the first-round.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;      m = 2               m = 3
+-------+------+    +-------+------+
| F(2k) | F(k) |    | F(2k) | F(k) |
+-------+------+    +-------+------+
| 1     | 1    |    | 1     | 1    |
+-------+------+    +-------+------+
| 3     | 2    |    | 2     | 2    |
+-------+------+    +-------+------+
| 5     | 3    |    | 4     | 3    |
+-------+------+    +-------+------+
| 7     | 4    |    | 5     | 4    |
+-------+------+    +-------+------+
| 9     | 5    |    | 7     | 5    |
+-------+------+    +-------+------+
                    | 8     | 6    |
                    +-------+------+
                    | 10    | 7    |
                    +-------+------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By looking at the table on the left, we can easily see that &lt;span class="math"&gt;\(F(2k) = 2F(k) - 1\)&lt;/span&gt;. 
However, there is no nice clean linear relation that we can get between &lt;span class="math"&gt;\(F(2k)\)&lt;/span&gt; and &lt;span class="math"&gt;\(F(k)\)&lt;/span&gt; 
when &lt;span class="math"&gt;\(n = 10\)&lt;/span&gt;, &lt;span class="math"&gt;\(m = 3\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;p&gt;Inside &lt;em&gt;Concrete Mathematics: A Foundation for Computer Science&lt;/em&gt;, after talking about the
solution to the Josephus problem, the author shift their focus to solve a generalized
recurrence of \ref{eq:1} and \ref{eq:2}, which is (1.11) in the book. This has nothing to do
with the Josephus problem and I’m guessing the reason why the author want to talk about 
the solution to the generalized recurrence is to illustrate dynamic programming philosophy.&lt;/p&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="general-solution"&gt;General solution&lt;/h2&gt;
&lt;p&gt;The big picture here is we need to find out the relative position of the final survivor to the
“first” person during each recursive call and then calculate the actual position for actual &lt;span class="math"&gt;\(n\)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The general solution utilitizes the dynamic programming paradigm by performing the first step
and using the solution of the subproblem we create to solve the initial problem. 
In terms of the solution, there is a difference when we start with the first person as &lt;span class="math"&gt;\(1\)&lt;/span&gt; or &lt;span class="math"&gt;\(0\)&lt;/span&gt;.&lt;/p&gt;
&lt;h3 id="starting-from-1"&gt;Starting from 1&lt;/h3&gt;
&lt;p&gt;The key insight is the following: the result of &lt;span class="math"&gt;\(J(n,m)\)&lt;/span&gt; is best NOT thought of as the &lt;em&gt;number&lt;/em&gt; that is the 
Josephus survivor, but rather as the &lt;em&gt;index&lt;/em&gt; of the number that is the Josephus survivor. &lt;/p&gt;
&lt;p&gt;Let’s first take a look an example when &lt;span class="math"&gt;\(n = 6\)&lt;/span&gt; and &lt;span class="math"&gt;\(m = 2\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fig.1

  1 2      1 X      1 X      1 X      1 X      X X
 6   3 -&amp;gt; 6   3 -&amp;gt; 6   3 -&amp;gt; X   3 -&amp;gt; X   X -&amp;gt; X   X
  5 4      5 4      5 X      5 X      5 X      5 X

fig.2

| index | 1 | 2 | 3 | 4 | 5 | 6 |
|-------|---|---|---|---|---|---|
| n = 6 | 1 | 2 | 3 | 4 | 5 | 6 | J(6,2) = 5
| n = 5 | 3 | 4 | 5 | 6 | 1 | 3 | J(5,2) = 3
| n = 4 | 5 | 6 | 1 | 3 | 5 | 6 | J(4,2) = 1
| n = 3 | 1 | 3 | 5 | 1 | 3 | 5 | J(3,2) = 3
| n = 2 | 5 | 1 | 5 | 1 | 5 | 1 | J(2,2) = 1
| n = 1 | 5 | 5 | 5 | 5 | 5 | 5 | J(1,2) = 1

fig.3

| index | 1 | 2 | 3 | 4 | 5 | 6 |
|-------|---|---|---|---|---|---|
| n = 6 | 1 | X | 3 | 4 | 5 | 6 | J(6,2) = 5 = (2-1 + 3) mod 6 + 1
| n = 5 | 3 | X | 5 | 6 | 1 | 3 | J(5,2) = 3 = (2-1 + 1) mod 5 + 1
| n = 4 | 5 | X | 1 | 3 | 5 | X | J(4,2) = 1 = (2-1 + 3) mod 4 + 1
| n = 3 | 1 | X | 5 | 1 | X | 5 | J(3,2) = 3 = (2-1 + 1) mod 3 + 1
| n = 2 | 5 | X | 5 | X | 5 | X | J(2,2) = 1 = (2-1 + 1) mod 2 + 1
| n = 1 | 5 | 5 | 5 | 5 | 5 | 5 | J(1,2) = 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By looking at fig.1, we know that &lt;span class="math"&gt;\(J(6,2) = 5\)&lt;/span&gt;. Now, if we take a look at fig.2, the row with &lt;span class="math"&gt;\(n = 5% shows that $J(5,2) = 3\)&lt;/span&gt;. By the insight,
&lt;span class="math"&gt;\(3\)&lt;/span&gt; here means the &lt;em&gt;index&lt;/em&gt; not the &lt;em&gt;number&lt;/em&gt;. So, our final survivor is &lt;span class="math"&gt;\(5\)&lt;/span&gt;, which is positioned on &lt;span class="math"&gt;\(3\)&lt;/span&gt; in this row.&lt;/p&gt;
&lt;p&gt;Let’s generalize the example a little bit. Suppose we want to know &lt;span class="math"&gt;\(J(n,2)\)&lt;/span&gt;. You can imagine 
we have &lt;span class="math"&gt;\(n\)&lt;/span&gt; people lined up like this: &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;1 2 3 4 5 ... n
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first thing that happens is that person &lt;span class="math"&gt;\(2\)&lt;/span&gt; get eliminated, as shown here:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;1 X 3 4 5 ... n
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we are left with a subproblem of the following form: there are &lt;span class="math"&gt;\(n - 1\)&lt;/span&gt; people remaining, every other
person is going to be eliminated, and the first person who will start to pass potato is person &lt;span class="math"&gt;\(3\)&lt;/span&gt;. In other 
words, the subproblem &lt;span class="math"&gt;\(J(n-1, 2)\)&lt;/span&gt; now looks like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;3 4 5 ... n 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span class="math"&gt;\(J(n-1, 2)\)&lt;/span&gt; will be the &lt;em&gt;index&lt;/em&gt; of who survives in a line of &lt;span class="math"&gt;\(n - 1\)&lt;/span&gt; of people. Given that we have the &lt;em&gt;index&lt;/em&gt;
of the person who will survive, and we also know who the starting person is, we can determine which person 
will be left. Here’s how we’ll do it.&lt;/p&gt;
&lt;p&gt;The starting person in this line is the person who comes right after the person who was last executed. This will 
be person &lt;span class="math"&gt;\(3\)&lt;/span&gt;. The 1-indexed position in the ring of &lt;span class="math"&gt;\(n-1\)&lt;/span&gt; people is given by &lt;span class="math"&gt;\(J(n-1, 2)\)&lt;/span&gt;. We can then walk 
forward &lt;span class="math"&gt;\(J(n-1, 2)\)&lt;/span&gt; positions, wrapping around the ring if necessary, to get our final position. In other words, the 
survivor is given by position&lt;/p&gt;
&lt;div class="math"&gt;$$
\begin{equation}
(3 + J(n-1, 2) - 1) \bmod n \label{eq:4}
\end{equation}
$$&lt;/div&gt;
&lt;p&gt;Let’s take a look at &lt;span class="math"&gt;\(n = 5\)&lt;/span&gt; in fig.2 again. Now, the starting position is &lt;span class="math"&gt;\(3\)&lt;/span&gt; and we walk forward by &lt;span class="math"&gt;\(J(5,2) - 1\)&lt;/span&gt; steps (i.e. &lt;span class="math"&gt;\(2\)&lt;/span&gt; steps) 
and we get the final survivor, which is &lt;span class="math"&gt;\(5\)&lt;/span&gt;. The reason we doing &lt;span class="math"&gt;\(\bmod n\)&lt;/span&gt; is because we want to keep final survivor within the bounds of the circle.&lt;/p&gt;
&lt;p&gt;However, there is a problem with our equation \ref{eq:4}. If we are indeed using one-indexing, what happens if the final survivor is at position &lt;span class="math"&gt;\(n\)&lt;/span&gt;?
In that case, we would accidentally get back position &lt;span class="math"&gt;\(0\)&lt;/span&gt; as our answer, but we really want position &lt;span class="math"&gt;\(n\)&lt;/span&gt;. For example, suppose &lt;span class="math"&gt;\(J(5,2) = 4\)&lt;/span&gt;. In other words,
the final survivor is &lt;span class="math"&gt;\(6\)&lt;/span&gt;, which is positioned at &lt;span class="math"&gt;\(4\)&lt;/span&gt; when &lt;span class="math"&gt;\(n = 5\)&lt;/span&gt;. Then, to apply equation \ref{eq:4}, we get &lt;span class="math"&gt;\(0\)&lt;/span&gt;, which is not &lt;span class="math"&gt;\(6\)&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;To fix this issue, we’ll use a trick for using mod to wrap around with one-indexing: we’ll take the inside quantity (the one-indexed position) and 
subtract one to get the zero-indexed position. We’ll mod that quantity by &lt;span class="math"&gt;\(n\)&lt;/span&gt; to get the zero-indexed position wrapped around. Finally, we’ll add 
back one to get the one-indexed position, wrapped around. That looks like:&lt;/p&gt;
&lt;div class="math"&gt;$$(3 + J(n-1, 2) - 2) \bmod n + 1$$&lt;/div&gt;
&lt;p&gt;In other words, &lt;span class="math"&gt;\(-2\)&lt;/span&gt; term comes from two independent &lt;span class="math"&gt;\(-1\)&lt;/span&gt;‘s: the first &lt;span class="math"&gt;\(-1\)&lt;/span&gt; is because &lt;span class="math"&gt;\(J(n-1, 2)\)&lt;/span&gt; returns a one-indexed index, so to step forward by
the right number of positions we have to take &lt;span class="math"&gt;\(J(n-1,2) - 1\)&lt;/span&gt; steps forward. The second &lt;span class="math"&gt;\(-1\)&lt;/span&gt; comes from the fact that we’re using one-indexing rather than
zero-indexing.&lt;/p&gt;
&lt;p&gt;Now, we’re finally ready to generalize the solution to arbitrary &lt;span class="math"&gt;\(m\)&lt;/span&gt;, not just &lt;span class="math"&gt;\(m = 2\)&lt;/span&gt;. After person &lt;span class="math"&gt;\(m\)&lt;/span&gt; get eliminated, we have an array like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;1 2 3 ... m-1 X m+1 ... n
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We now essentailly need to solve a subproblem where person &lt;span class="math"&gt;\(m+1\)&lt;/span&gt; comes first:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;m+1 m+2 ... n 1 2 ... m-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So we compute &lt;span class="math"&gt;\(J(n-1, m)\)&lt;/span&gt; to get the one-indexed survivor of a ring of &lt;span class="math"&gt;\(n-1\)&lt;/span&gt; people, then shift forward by that many steps:&lt;/p&gt;
&lt;div class="math"&gt;$$(m+1 + J(n-1, m) - 1)$$&lt;/div&gt;
&lt;p&gt;We need to worry about the case where we wrap around, so we need to mod by &lt;span class="math"&gt;\(n\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;$$(m+1 + J(n-1, m) - 1) \bmod n$$&lt;/div&gt;
&lt;p&gt;However, we’re one-indexed, so we need to use the trick of subtracing &lt;span class="math"&gt;\(1\)&lt;/span&gt; from the inside quantity and then adding &lt;span class="math"&gt;\(1\)&lt;/span&gt; at the end:&lt;/p&gt;
&lt;div class="math"&gt;$$(m+1 + J(n-1, m) - 2) \bmod n + 1$$&lt;/div&gt;
&lt;p&gt;which simplifies to:&lt;/p&gt;
&lt;div class="math"&gt;$$(m-1 + J(n-1, m)) \bmod n + 1$$&lt;/div&gt;
&lt;p&gt;Notice that &lt;span class="math"&gt;\(J(1,m) = 1\)&lt;/span&gt;, which indicates that we’re one-indexed.&lt;/p&gt;
&lt;h3 id="starting-from-0"&gt;Starting from 0&lt;/h3&gt;
&lt;p&gt;Since we are not in zero-indexed. Our &lt;span class="math"&gt;\(J(6,2)\)&lt;/span&gt; example looks like the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;| index | 0 | 1 | 2 | 3 | 4 | 5 |
|-------|---|---|---|---|---|---|
| n = 6 | 1 | 2 | 3 | 4 | 5 | 6 | J(6,2) = 4 = (2 + 2 ) mod 6
| n = 5 | 3 | 4 | 5 | 6 | 1 | 3 | J(5,2) = 2 = (0 + 2 ) mod 5
| n = 4 | 5 | 6 | 1 | 3 | 5 | 6 | J(4,2) = 0 = (2 + 2 ) mod 4
| n = 3 | 1 | 3 | 5 | 1 | 3 | 5 | J(3,2) = 2 = (0 + 2 ) mod 3
| n = 2 | 5 | 1 | 5 | 1 | 5 | 1 | J(2,2) = 0 = (0 + 2 ) mod 2 
| n = 1 | 5 | 5 | 5 | 5 | 5 | 5 | J(1,2) = 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s apply the same logic from the one-indexed case. After person &lt;span class="math"&gt;\(m-1\)&lt;/span&gt; get eliminated, we have an array like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;0 1 2 ... m-2 X m ... n-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We now essentailly need to solve a subproblem where person &lt;span class="math"&gt;\(m\)&lt;/span&gt; comes first:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;m m+1 ... n-1 0 1 2 ... m-2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, we compute &lt;span class="math"&gt;\(J(n-1,m)\)&lt;/span&gt; to give us the zero-indexed survivor of a ring of &lt;span class="math"&gt;\(n-1\)&lt;/span&gt; people and we shfit forward by that many steps:&lt;/p&gt;
&lt;div class="math"&gt;$$(m + J(n-1,m))$$&lt;/div&gt;
&lt;p&gt;We take care of wrapping around by mod &lt;span class="math"&gt;\(n\)&lt;/span&gt;:&lt;/p&gt;
&lt;div class="math"&gt;$$(m + J(n-1,m)) \bmod n$$&lt;/div&gt;
&lt;p&gt;Since we are zero-indexed, we are done. If we want to transform our answer to one-indexed, we can do:&lt;/p&gt;
&lt;div class="math"&gt;$$(m + J(n-1,m) \bmod n + 1$$&lt;/div&gt;
&lt;p&gt;Note that &lt;span class="math"&gt;\(J(1,m) = 0\)&lt;/span&gt; in this case, which indicates that we’re zero-indexed.&lt;/p&gt;
&lt;!-- ### Implementation --&gt;
&lt;!-- There are many ways to solve this question. --&gt;
&lt;!-- *Brute force* --&gt;
&lt;!-- We can use a cricular double linked list to implement the solution. --&gt;
&lt;!-- *Recurrence* --&gt;
&lt;!-- Use the recurrence relation we just derived. --&gt;
&lt;h2 id="whats-left-out"&gt;What’s left out&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blue.butler.edu/~phenders/InRoads/MathCounts8.pdf"&gt;Equivalence Class Solution&lt;/a&gt; is interesting to check out.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.scribd.com/document/3567390/Rank-Trees"&gt;Rank tree&lt;/a&gt; as a data sturcture is worth to check out to solve this problem. &lt;a href="http://www.imt.ro/romjist/Volum12/Number12_1/pdf/02-MCosulschi.pdf"&gt;This paper&lt;/a&gt; gives a more detailed analysis.&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- ## Reference --&gt;
&lt;!-- - https://en.wikipedia.org/wiki/Josephus_problem --&gt;
&lt;!-- - Graham, R.L.; Knuth, D.E.; Patashnik, O. (1989), Concrete Mathematics: A Foundation for Computer Science, Addison Wesley, p. 8, ISBN 978-0-201-14236-5 --&gt;
&lt;!-- - http://www.cut-the-knot.org/recurrence/r_solution.shtml --&gt;
&lt;!-- - http://www.exploringbinary.com/powers-of-two-in-the-josephus-problem --&gt;
&lt;!-- - http://www.math.northwestern.edu/~mlerma/problem_solving/solutions/josephus.pdf --&gt;
&lt;!-- - http://blue.butler.edu/~phenders/InRoads/MathCounts8.pdf --&gt;
&lt;!-- - http://stackoverflow.com/questions/31775604/explanation-for-recursive-implementation-of-josephus-prob?answertab=active#tab-top --&gt;
&lt;!-- - http://stackoverflow.com/questions/21737771/can-someone-please-explain-the-use-of-modulus-in-this-code?rq=1 --&gt;
&lt;!-- - https://rosettacode.org/wiki/Josephus_problem --&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="2016"></category><category term="recursion"></category><category term="dynamic programming"></category><category term="math"></category><category term="maw"></category></entry><entry><title>A peek in code optimization</title><link href="https://zhu45.org/posts/2016/Dec/28/a-peek-in-code-optimization/" rel="alternate"></link><published>2016-12-28T13:21:00+08:00</published><updated>2016-12-28T13:21:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-28:/posts/2016/Dec/28/a-peek-in-code-optimization/</id><summary type="html">&lt;p class="first last"&gt;MAW 3.9 solution optimization&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Quite often, when I take a look at a programming
question solution, I'm amazed by how succint the provided
solution is. However, it is also known that getting an "optimized"
solution is often taking iterative approach. This is something
that I didn't realize until I start to work in the industry.&lt;/p&gt;
&lt;p&gt;This post is mainly a reminder to keep reminding myself about this point:
We don't have to give a perfect solution right away. We can provide a
solution and gradually make it better.&lt;/p&gt;
&lt;p&gt;The example I show here is &lt;tt class="docutils literal"&gt;integerList add(integerList A, integerList B)&lt;/tt&gt;,
which is part of &lt;a class="reference external" href="https://zhu45.org/posts/2016/Dec/26/reflection-on-integer-arithmetic-package-problem/"&gt;MAW 3.9 integer arithmetic package question&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="mi"&gt;-10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// example case: 342 + 706&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The idea for this first iteration solution stems from MAW 3.5
&lt;a class="reference external" href="https://github.com/xxks-kkk/algo/blob/master/linkedList/generic/linkedList.c"&gt;List unionSortedLists(List L, List P)&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
Given two sorted lists, L and P, write a procedure to compute L1 union L2 using
only the basic list operations.&lt;/blockquote&gt;
&lt;p&gt;Since we put the least significant digit as the very first data node and we
put the most significant digit as the last data node, we walk through the list.
If you compare this routine with &lt;tt class="docutils literal"&gt;unionSortedLists&lt;/tt&gt; routine, you can easily
find that both routine structure is composed of three while loops. This makes sense
because &lt;tt class="docutils literal"&gt;union&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;add&lt;/tt&gt; are extremely similar mathematically.&lt;/p&gt;
&lt;p&gt;First we start by adding the unit digit. If both numbers have the same number of digits,
then we are done afte the first while loop. There is a special case where we still have
a carry after we processed all the digits. If number of digits for two numbers are not the same,
then we just move extra digits to the result.&lt;/p&gt;
&lt;p&gt;Let's see how we can optimize this code.&lt;/p&gt;
&lt;p&gt;In the solution, we build the case around the number of digits that operands have.
However, this is necessary because in the case that two numbers have different number of digits,
we can add leading zeros to the beginning of the number with fewer digits. This will make
adding two numbers with different number of digits the same as adding two numbers with the same
number of digits. So, we eliminate the latter two while loops and only need to keep the first while
loop in the original solution.&lt;/p&gt;
&lt;p&gt;Here is the final result.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;
&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;makeEmpty&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digitSum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// example case: 342 + 706&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</content><category term="Data Struct &amp; Algo"></category><category term="linked-list"></category><category term="software-engineering"></category></entry><entry><title>Reflection on integer arithmetic package problem</title><link href="https://zhu45.org/posts/2016/Dec/26/reflection-on-integer-arithmetic-package-problem/" rel="alternate"></link><published>2016-12-26T23:03:00+08:00</published><updated>2016-12-26T23:03:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-26:/posts/2016/Dec/26/reflection-on-integer-arithmetic-package-problem/</id><summary type="html">&lt;p class="first last"&gt;Origin from MAW 3.9&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This weekend, I'm working on MAW 3.9. The single problem results
in almost 500 lines of code. This is quite unexpected. The problem
is stated as the following:&lt;/p&gt;
&lt;blockquote&gt;
Write an arbitrary-precision integer arithmetic package. You should
use a strategy similar to polynomial arithmetic. Compute the distribution
of the digits &lt;span class="math"&gt;\(0\)&lt;/span&gt; to &lt;span class="math"&gt;\(9\)&lt;/span&gt; in &lt;span class="math"&gt;\(2^{4000}\)&lt;/span&gt;.&lt;/blockquote&gt;
&lt;p&gt;This post is the reflection about this problem.&lt;/p&gt;
&lt;div class="section" id="which-way-to-go"&gt;
&lt;h2&gt;Which way to go?&lt;/h2&gt;
&lt;p&gt;Since the problem states "arbitrary-precision" and "use a strategy similar to
polynomial arithmetic", then I can conclude that linked list is the best data
structure for this problem. However, the question is how we can construct the
linked list to best implement our integer arithmetic operations (i.e. addition,
mulitiplication)?&lt;/p&gt;
&lt;p&gt;We essentially have two options:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;We put the most significant digit as the the very first data node and
we put the least significant digit as the last data node. For example,
for a number &lt;span class="math"&gt;\(123\)&lt;/span&gt;, we will implement it like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dummy-&amp;gt;1-&amp;gt;2-&amp;gt;3&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;This is the exactly opposite of the first option. We put the least significant
digit as the very first data node and we put the most significant digit as
the last data node. Again, for &lt;span class="math"&gt;\(123\)&lt;/span&gt;, we will implement is like
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dummy-&amp;gt;3-&amp;gt;2-&amp;gt;1&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let's evaluate these two options from two perspective:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Whether we can easily construct a linked list to represent arbitrary-precision integer?&lt;/li&gt;
&lt;li&gt;Whether the arithmetic operations are essy to implement?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From the first perspective, for option one, each time we add a new digit to the most significant position, we insert
a new node at the very beginning of the list (i.e. right after the header node).
On the other hand, for option two, we append a new node
at the very end of the list. Since we design our &lt;tt class="docutils literal"&gt;addDigit&lt;/tt&gt; with an input of a pointer to node (i.e. to specify
where to add node), these two options work equally well.&lt;/p&gt;
&lt;p&gt;From the second perspective, things are different. Take arithmetic addition as an example. When we try to add
two numbers, for option one, we need to walk through the whole list to begin with the very end of the node
because we want to start with unit digit. This makes our routine complex because we need to use a while loop
to walk through the list first. For second option, situation is easier becauuse the number is implemented in the
reverse order in the list. The very first data node is the unit digit and we can directly start with addition
while we move towards the end of the list. If we need to add additional node because of carry (i.e. &lt;span class="math"&gt;\(999 + 1\)&lt;/span&gt;
will be no longer 3-digit but 4-digit number), we can naturally pass the pointer pointing towards the current node to
the &lt;tt class="docutils literal"&gt;addDigit&lt;/tt&gt; function.&lt;/p&gt;
&lt;p&gt;So, we choose option two to implement our integer package.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="memory-leak"&gt;
&lt;h2&gt;Memory leak&lt;/h2&gt;
&lt;p&gt;Memory leak is a very important issue to pay attention to during the testing phase. We use &lt;a class="reference external" href="http://valgrind.org/"&gt;valgrind&lt;/a&gt;
to help us detect if there is any leak in our code. You can reference &lt;a class="reference external" href="http://valgrind.org/docs/manual/quick-start.html#quick-start.intro"&gt;their quick start guide&lt;/a&gt;
and &lt;a class="reference external" href="http://valgrind.org/docs/manual/mc-manual.html#mc-manual.errormsgs"&gt;memory check user manual&lt;/a&gt; for the commands and error shooting.&lt;/p&gt;
&lt;p&gt;Here are the two mistakes I made (You can check out &lt;a class="reference external" href="https://github.com/xxks-kkk/algo/commit/299ebb9a90791612343f194d9eec1ed3909c97b3#diff-5db0d6074a742e1a08d3bb60c69e5a21"&gt;my commit about memory leak debug&lt;/a&gt;):&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Always &lt;tt class="docutils literal"&gt;free&lt;/tt&gt; the chunk allocated by &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt; whenever possible.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Take &lt;tt class="docutils literal"&gt;multiply&lt;/tt&gt; function as an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;
&lt;span class="normal"&gt;51&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;makeEmpty&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;makeEmpty&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;addDigit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// prevent memory leak&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;deleteAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;deleteIntegerList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyTmpR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;deleteAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;We allocate &lt;tt class="docutils literal"&gt;tmpR&lt;/tt&gt; through &lt;tt class="docutils literal"&gt;makeEmpty()&lt;/tt&gt; in Line[7]. If we don't do anything about it
inside the function, then the memory will be lost because we have no way to reference this
chunk of memory outside the function. Local variable &lt;tt class="docutils literal"&gt;tmpR&lt;/tt&gt; is the only reference to the
memory allocated on the heap. However, once the function is done, the local variable is destroyed
from the stack, and thus, we lose our only reference to the memory chunk. So, we need to free it
before we exit the function (Line[49]).&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;Be careful with a function call inside a function call.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This type of leak is much more subtle than the first one. Originally instead of&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;deleteAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I only have &lt;tt class="docutils literal"&gt;R = add(R, tmpR)&lt;/tt&gt;. This cause the leak because of the following reasoning:
Originally, we have &lt;tt class="docutils literal"&gt;R&lt;/tt&gt; points to a list of nodes. When we do &lt;tt class="docutils literal"&gt;add(R,tmpR)&lt;/tt&gt;, we create
a new list of nodes, which hold our addition result. Then we let &lt;tt class="docutils literal"&gt;R&lt;/tt&gt; points towards this newly-created
list. This makes us lose the list of nodes originally pointed by &lt;tt class="docutils literal"&gt;R&lt;/tt&gt;. That's why we introduce &lt;tt class="docutils literal"&gt;tmp&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="makeempty"&gt;
&lt;h2&gt;makeEmpty ?&lt;/h2&gt;
&lt;p&gt;Originally, I don't have this &lt;tt class="docutils literal"&gt;makeEmpty&lt;/tt&gt; function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;
&lt;span class="nf"&gt;makeEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;integerList&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;NextDigit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// super important step&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you take a look at this function, it seems to be a wrapper around &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt; operation, which
seems redundant (we could directly call &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt; directly in the place that &lt;tt class="docutils literal"&gt;makeEmpty&lt;/tt&gt; appears).
However, the key for this routine is &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;R-&amp;gt;NextDigit&lt;/span&gt; = NULL;&lt;/tt&gt;. This step can be easily omitted. However,
without this step, we don't have fully control on what our newly-allocated empty list (i.e. a list with only
header node) will look like. In other words, our header node will point to somewhere (i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;R-&amp;gt;NextDigit&lt;/span&gt;&lt;/tt&gt;) randomly without
our key step. This can cause serious trouble for the following routine debug. For example, we could have &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;R-&amp;gt;NextDigit&lt;/span&gt;&lt;/tt&gt;
holds some address value that happens to have a node structure there with a value in it. For instance, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dummy-&amp;gt;1&lt;/span&gt;&lt;/tt&gt;.
This can usually happen when you OS try to reuse the memory chunk you previously freed. For example, try the following experiment:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;replace &lt;tt class="docutils literal"&gt;makeEmpty&lt;/tt&gt; on Line[7] &amp;amp; line[10] in &lt;tt class="docutils literal"&gt;multiply&lt;/tt&gt; function&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;multiply&lt;/tt&gt; works fine with &lt;tt class="docutils literal"&gt;test_multiply()&lt;/tt&gt; solely in the test program.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;multiply&lt;/tt&gt; won't work if we do &lt;tt class="docutils literal"&gt;test_intializeInteger()&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;test_add()&lt;/tt&gt; before &lt;tt class="docutils literal"&gt;test_multiply()&lt;/tt&gt;
because the integer we construct will no longer be &lt;tt class="docutils literal"&gt;342&lt;/tt&gt; in the test case but something like &lt;tt class="docutils literal"&gt;3425&lt;/tt&gt;, where
&lt;tt class="docutils literal"&gt;5&lt;/tt&gt; is some value pointed by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;R-&amp;gt;NextDigit&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, always clear out the pointer by setting it to &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; whenever we do initialization.&lt;/p&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="software-engineering"></category><category term="c"></category></entry><entry><title>A small C trick I learned today</title><link href="https://zhu45.org/posts/2016/Dec/24/a-small-c-trick-i-learned-today/" rel="alternate"></link><published>2016-12-24T23:11:00+08:00</published><updated>2016-12-24T23:11:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-24:/posts/2016/Dec/24/a-small-c-trick-i-learned-today/</id><summary type="html">&lt;p class="first last"&gt;A C one-liner&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Today I learned a C trick. Here is my original &lt;tt class="docutils literal"&gt;printList&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;printList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// creates a dummy node to traverse the list&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d-&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works but there is a small caveat in this routine. This is
part of print out for the &lt;tt class="docutils literal"&gt;linkedListTestMain&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
TEST: printList
23-&amp;gt;44-&amp;gt;45-&amp;gt;57-&amp;gt;89-&amp;gt;-1-&amp;gt;
&lt;/pre&gt;
&lt;p&gt;As you can see, there is a little &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt; at the end of linked list, which
is not supposed to be there because there is no next element after &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-1&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;I try to solve this problem but the solution is not succint and I don't want to
do complicated stuff just to remove this &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt;. Howver, I finally get a solution
today that is very clean to eliminate &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt; without adding additional complexity to
the routine.&lt;/p&gt;
&lt;p&gt;In C, we know we can use if-else shorthand likes the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;is equivalent with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can use this shorthand inside our routine &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt; statement to solve our problem:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;printList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// creates a dummy node to traverse the list&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, inside &lt;tt class="docutils literal"&gt;printf&lt;/tt&gt; statement, we don't printout &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt; by default, we check
if &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;dummy-&amp;gt;Next&lt;/span&gt;&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt;, then that means we are at the last element of the list, and
we don't append anything (i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;("")&lt;/span&gt;&lt;/tt&gt;). However, if this is not the case, we print &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
</content><category term="programming languages"></category><category term="c"></category></entry><entry><title>Print singly linked list in reverse order</title><link href="https://zhu45.org/posts/2016/Dec/23/print-singly-linked-list-in-reverse-order/" rel="alternate"></link><published>2016-12-23T00:05:00+08:00</published><updated>2016-12-23T00:05:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-23:/posts/2016/Dec/23/print-singly-linked-list-in-reverse-order/</id><summary type="html">&lt;p class="first last"&gt;See above&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Today, during the lunch break, I take a look at the following problem:&lt;/p&gt;
&lt;blockquote&gt;
Print a singly linked list in reverse order.&lt;/blockquote&gt;
&lt;p&gt;This is actually one of the interview questions I got at SAP for ABAP developer position
(luckily, they didn't offer me the position). I didn't get the correct answer at that time
and I think the problem may help me to kill some time during the break.&lt;/p&gt;
&lt;p&gt;The question itself is not hard if you're familar with linked list and recursion philosophy:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;printListReverseHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printListReverseHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d-&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;printListReverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printListReverseHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, in our implementation of linked list, we use header node. Given the simiplicity of the problem,
I think it is good time to revisit some basic rules in recursion.&lt;/p&gt;
&lt;p&gt;To be honest, recursion always gives me hard time because I always try to mentally expand all the call
stack and then work backwards to see if the recursion function gives what I expect. This is super energy
consuming and error-prone.&lt;/p&gt;
&lt;p&gt;However, things start to get better since I start to read MAW. Here are the four basic rules of recursion
he emphasizes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;em&gt;Base cases.&lt;/em&gt; You must always have some base cases, which can be solved without recursion.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Making progress.&lt;/em&gt; For the cases that are to be solved recursively, the recursive call must always
be to a case that makes progress toward a base case.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Design rule.&lt;/em&gt; Assume that all the recursive calls work.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Compound interest rule.&lt;/em&gt; Never duplicate work by solving the same instance of a problem in separate
recursive calls.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;Among the four rules, No.3 rule is easily my most faviroite one. It is stated very simple but it has huge
impact on how you think about recursion.&lt;/p&gt;
&lt;p&gt;Let's use first three rules to analyze this problem a little bit.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;em&gt;Base cases.&lt;/em&gt; This problem is quite simple. The base case is the case when the list is empty. In this case,
we have nothing to do and simply return.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Making progress.&lt;/em&gt; This is reflected when we call &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;printListReverseHelper(L-&amp;gt;Next)&lt;/span&gt;&lt;/tt&gt;. Each time we make the
recursive call, we pass in &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;L-&amp;gt;Next&lt;/span&gt;&lt;/tt&gt;, which makes the list shorter. This eventually will make the whole list
empty, which is the base case.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Design rule.&lt;/em&gt; I use this rule to design the whole recursion function. Just imagaine a scenario like the following:
Suppose you have a list of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;1-&amp;gt;2-&amp;gt;3&lt;/span&gt;&lt;/tt&gt;. Then, by the rule, we assume that the number &lt;tt class="docutils literal"&gt;2&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;3&lt;/tt&gt; are already printed
in reverse order. What we left to do is to print out &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; and then we done. We follow this thought process closely
when we actually write the recursion function. After we write out the base case, we first write &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;printListReverseHelper(L-&amp;gt;Next);&lt;/span&gt;&lt;/tt&gt;
This is saying that the rest of list (except the first one) is already printed in reverse order (i.e. &lt;tt class="docutils literal"&gt;2&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;3&lt;/tt&gt; in our case).
Then we write &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;printf("%d-&amp;gt;",&lt;/span&gt; &lt;span class="pre"&gt;L-&amp;gt;Element);&lt;/span&gt;&lt;/tt&gt;. This says, ok, since we are only left with the first node, let's print it out and the
job is done (i.e. &lt;tt class="docutils literal"&gt;1&lt;/tt&gt; in our case).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See, how simple the recursion can be if we can actually get over psychological obstacle to expand the call stack mentally and directly apply
four rules (especially the third rule) to design our function.&lt;/p&gt;
</content><category term="Data Struct &amp; Algo"></category><category term="linked-list"></category><category term="recursion"></category></entry><entry><title>Environment variable substitution using Sed</title><link href="https://zhu45.org/posts/2016/Dec/21/environment-variable-substitution-using-sed/" rel="alternate"></link><published>2016-12-21T12:07:00+08:00</published><updated>2016-12-21T12:07:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-21:/posts/2016/Dec/21/environment-variable-substitution-using-sed/</id><summary type="html">&lt;p class="first last"&gt;A &lt;tt class="docutils literal"&gt;sed&lt;/tt&gt; example&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Suppose we have a text file &lt;tt class="docutils literal"&gt;config.ini&lt;/tt&gt; looks something like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[MSSQLSERVER]
Driver=INSTHOME/foo/foo.so

[SYBASE]
Driver=INSTHOME/bar/bar.so

...
&lt;/pre&gt;
&lt;p&gt;We want to replace all the appearance of &lt;tt class="docutils literal"&gt;INSTHOME&lt;/tt&gt; with the
value we hold in &lt;tt class="docutils literal"&gt;$HOME&lt;/tt&gt;. Here is what I do initially:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s/INSTHOME/&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/g"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;config.ini
&lt;/pre&gt;&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;s&lt;/tt&gt; is used to replace the found expression &lt;tt class="docutils literal"&gt;INSTHOME&lt;/tt&gt; with &lt;tt class="docutils literal"&gt;$HOME&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;g&lt;/tt&gt; stands for "global", which means to do this find &amp;amp; replace
for the whole line. If you leave off the &lt;tt class="docutils literal"&gt;g&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;INSTHOME&lt;/tt&gt; appears
twice on the same line, only the first &lt;tt class="docutils literal"&gt;INSTHOME&lt;/tt&gt; is changed to &lt;tt class="docutils literal"&gt;$HOME&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-i&lt;/span&gt;&lt;/tt&gt; is used to edit in place on filename&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-e&lt;/span&gt;&lt;/tt&gt; is to indicate the expression/command to run&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;I use double quotes &lt;tt class="docutils literal"&gt;"&lt;/tt&gt; to expand any variable appeard
inside &lt;tt class="docutils literal"&gt;"&lt;/tt&gt;. In this case, &lt;tt class="docutils literal"&gt;$HOME&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;However, when I type this in and I got the following error:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sed: -e expression #1, char 13: unknown option to `s'
&lt;/pre&gt;
&lt;p&gt;Why did this error happen? That confused me for a while. Then, I try to
simulate what the program will do for the above expression:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s/INSTHOME//home/iidev20/g"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;config.ini
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ah! This expansion result doesn't make sense at all because &lt;tt class="docutils literal"&gt;sed&lt;/tt&gt; expression
inside &lt;tt class="docutils literal"&gt;"&lt;/tt&gt; needs to follow:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"s/[target_expression]/[replace_expression/g"
&lt;/pre&gt;
&lt;p&gt;So, the first thought comes to me is to escape all &lt;tt class="docutils literal"&gt;/&lt;/tt&gt; in the expression:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s/INSTHOME/\/home\/iidev20/g"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;config.ini
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This can work but it has two severe drawbacks:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;I'm hardcoding the value. If &lt;tt class="docutils literal"&gt;$HOME&lt;/tt&gt; no longer holds &lt;tt class="docutils literal"&gt;/home/iidev20&lt;/tt&gt;,
then my command breaks again, and this hinders portability.&lt;/li&gt;
&lt;li&gt;The readability of this code is too bad. Probably okay for Perl programmer but
still, not quite friendly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To address these two issues, I find the following about &lt;a class="reference external" href="https://www.gnu.org/software/sed/manual/html_node/Addresses.html#Addresses"&gt;GNU sed&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;%regexp%&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first"&gt;(The % may be replaced by any other single character.)&lt;/p&gt;
&lt;blockquote class="last"&gt;
This also matches the regular expression regexp, but allows one to use a different delimiter than /. This is particularly useful if the regexp itself contains a lot of slashes, since it avoids the tedious escaping of every /. If regexp itself includes any delimiter characters, each must be escaped by a backslash ().&lt;/blockquote&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/blockquote&gt;
&lt;p&gt;Essentially, we don't have to use &lt;tt class="docutils literal"&gt;/&lt;/tt&gt; as our delimiter for the expression, especially when the pattern itself contains a lot of slashes (i.e. file path in my case).&lt;/p&gt;
&lt;p&gt;so, I decide to use &lt;tt class="docutils literal"&gt;|&lt;/tt&gt; as the delimiter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s|INSTHOME|&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;|g"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;config.ini
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;I can also use single quote &lt;tt class="docutils literal"&gt;'&lt;/tt&gt; but the command should be modified like the below
by leaving out to-be-expanded variable name outside of single quotes.&lt;/p&gt;
&lt;div class="last"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'s|INSTHOME|'&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s1"&gt;'|g'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;config.ini
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now, everything works nice and clean.&lt;/p&gt;
</content><category term="tools"></category><category term="sed"></category><category term="shell"></category></entry><entry><title>What's the difference between sourcing a script and executing a script?</title><link href="https://zhu45.org/posts/2016/Dec/20/whats-the-difference-between-sourcing-a-script-and-executing-a-script/" rel="alternate"></link><published>2016-12-20T21:49:00+08:00</published><updated>2016-12-20T21:49:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-20:/posts/2016/Dec/20/whats-the-difference-between-sourcing-a-script-and-executing-a-script/</id><summary type="html">&lt;p class="first last"&gt;Amusing question in shell&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I run across the question in the title when I take a break from the work
today. Then I did a little bit googling, and the explanation is not quite satisfying
to me. So, I decide to answer this question by a simplied example from my work.&lt;/p&gt;
&lt;p&gt;For me, this question appears frequently when you try to install some software.
Some software, like the product I'm working on, depends on a set of environment variables
in order to setup itself properly. Usually, this may inovlve manual editing of the environment
variables in order to make the product work. However, we can do much better.
We can somehow let a setup program to edit the environment variable for the user and finish
the whole product setup process automatically.&lt;/p&gt;
&lt;p&gt;Suppose a software relies on an environment variable &lt;tt class="docutils literal"&gt;TEST_SOURCE&lt;/tt&gt; and
we don't have such an environment variable initially.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$TEST_SOURCE&lt;/span&gt;
$
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If we create a test script &lt;tt class="docutils literal"&gt;test.sh&lt;/tt&gt; like the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;TEST_SOURCE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;HELLO
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we can have two way to execute this script: either by &lt;tt class="docutils literal"&gt;./test.sh&lt;/tt&gt; or
by &lt;tt class="docutils literal"&gt;source test.sh&lt;/tt&gt; and they two have different outcome:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;./test.sh
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$TEST_SOURCE&lt;/span&gt;
$
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;test.sh
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$TEST_SOURCE&lt;/span&gt;
HELLO
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, the conclusion is that when we execute in &lt;tt class="docutils literal"&gt;source&lt;/tt&gt;, we actually run program
in the current shell. However, if we execute in &lt;tt class="docutils literal"&gt;./&lt;/tt&gt;, then we run the program
in a separately shell and the execution (i.e. modify environment variable) doesn't
impact our current shell.&lt;/p&gt;
&lt;!-- http://www.theeggeadventure.com/wikimedia/index.php/Interview_Questions --&gt;
</content><category term="tools"></category><category term="shell"></category></entry><entry><title>Polynomial Multiplication</title><link href="https://zhu45.org/posts/2016/Dec/18/polynomial-multiplication/" rel="alternate"></link><published>2016-12-18T18:53:00+08:00</published><updated>2016-12-18T18:53:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-18:/posts/2016/Dec/18/polynomial-multiplication/</id><summary type="html">&lt;p class="first last"&gt;Origin from MAW 3.7&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I finally got time to continue working through MAW. The problem 3.7 relates to polynomial multiplication.&lt;/p&gt;
&lt;div class="section" id="problem"&gt;
&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;Write a function to multiply two polynomials, using a linked list implementation. You must make sure that
the output polynomial is sorted by exponent and has at most one term of any power.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;Give an algorithm to solve this problem in &lt;span class="math"&gt;\(O(M^2N^2)\)&lt;/span&gt; time.&lt;/li&gt;
&lt;li&gt;Write a program to perform the multiplication in &lt;span class="math"&gt;\(O(M^2N)\)&lt;/span&gt; time, where &lt;span class="math"&gt;\(M\)&lt;/span&gt; is the number
of terms in the polynomiial of fewer terms.&lt;/li&gt;
&lt;li&gt;Write a program to perform the multiplication in &lt;span class="math"&gt;\(O(MNlog(MN))\)&lt;/span&gt; time.&lt;/li&gt;
&lt;li&gt;Which time bound above is the best?&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;div class="section" id="question-1"&gt;
&lt;h3&gt;Question 1&lt;/h3&gt;
&lt;p&gt;The first question is quite straightforward. We keep the result in a linked list with
exponent sorted in descending order. Each time a multiply is performed, we search through
the result linkedlist for the term with the same exponent as ours. If so, we simply add
coefficients together. If not, we add our product as a new term.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;
&lt;span class="nf"&gt;multiply1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyRPrev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpExponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpCoefficient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;tmpExponent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;tmpCoefficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// we go through the output polynomial to see if there is&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// a term with the same exponent as our tmpExponent.&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpExponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpCoefficient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;dummyRPrev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// We couldn't find the term with the same exponent, so we create&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// a new term in our output polynomial.&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpCoefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpExponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyRPrev&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;dummyR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The total running time is &lt;span class="math"&gt;\(O(M*N)\)&lt;/span&gt;. We start from the inner most loop. We
go through the result linkedList to search for the duplicate exponent term. The running
time depends on the length of the linkedList. The result linkedList can have at most
&lt;span class="math"&gt;\(M*N\)&lt;/span&gt; terms. Then, for the middle loop, we iterate through &lt;span class="math"&gt;\(N\)&lt;/span&gt; times and
for the outer most loop, we iterate through &lt;span class="math"&gt;\(M\)&lt;/span&gt; times. So, the total running time
is &lt;span class="math"&gt;\(O(M*N*MN) = O(M^2N^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="question-2"&gt;
&lt;h3&gt;Question 2&lt;/h3&gt;
&lt;p&gt;We can certainly do better than &lt;span class="math"&gt;\(O(M^2N^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;
&lt;span class="nf"&gt;multiply2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lenA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lenB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Polynomial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;lenA&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyA&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;lenB&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyB&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lenA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lenB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyTmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tmp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coefficient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;dummyTmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyTmp&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyLong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;deletePolynomial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Tmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyShort&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Suppose polynomials &lt;span class="math"&gt;\(A\)&lt;/span&gt; has &lt;span class="math"&gt;\(M\)&lt;/span&gt; terms, and polynomials
&lt;span class="math"&gt;\(B\)&lt;/span&gt; has &lt;span class="math"&gt;\(N\)&lt;/span&gt; terms. &lt;span class="math"&gt;\(M &amp;lt; N\)&lt;/span&gt;.
Instead of updating the result after each multiply, we multiply one term
from &lt;span class="math"&gt;\(A\)&lt;/span&gt; (the polynomials with fewer terms) by all the terms from
&lt;span class="math"&gt;\(B\)&lt;/span&gt; (the polynomials with more terms). Then we add this with the output
linkedList using &lt;tt class="docutils literal"&gt;Polynomial &lt;span class="pre"&gt;add(...)&lt;/span&gt;&lt;/tt&gt; function I implemented (can be found under
&lt;a class="reference external" href="https://github.com/xxks-kkk/algo/blob/master/linkedList/polynomial/polynomial.c"&gt;polynomial.c&lt;/a&gt;).
The &lt;tt class="docutils literal"&gt;add&lt;/tt&gt; function has a runtime &lt;span class="math"&gt;\(O(max(M,N))\)&lt;/span&gt; and thus we can get our runtime for &lt;tt class="docutils literal"&gt;multiply2&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
O(max(N,0)) + O(max(N,N)) + O(max(N,2N)) + ... + O(max(N, N(M-1))) = O(M^2N)
\end{equation*}
&lt;/div&gt;
&lt;p&gt;Also, we calculate the length of &lt;span class="math"&gt;\(A\)&lt;/span&gt; taking &lt;span class="math"&gt;\(O(M)\)&lt;/span&gt;; we calculate the length of &lt;span class="math"&gt;\(B\)&lt;/span&gt;
taking &lt;span class="math"&gt;\(O(N)\)&lt;/span&gt;; and we do &lt;tt class="docutils literal"&gt;deleteList&lt;/tt&gt; during the while loop taking &lt;span class="math"&gt;\(O(MN)\)&lt;/span&gt;. So, the total runtime is:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
O(M^2 N) + O(M) + O(N) + O(MN) = O(M^2 N)
\end{equation*}
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For this implementation, I kind of using an interface within the function. The logic
begins with &lt;tt class="docutils literal"&gt;while (dummyShort != NULL)&lt;/tt&gt; are the same for both &lt;span class="math"&gt;\(M&amp;lt;N\)&lt;/span&gt; and &lt;span class="math"&gt;\(M&amp;gt;N\)&lt;/span&gt;.
So, there is potential to write the same logic twice for these two cases respectively. The solution
I use is to provide an interface using &lt;tt class="docutils literal"&gt;dummyLong&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;dummyShort&lt;/tt&gt; variables.&lt;/p&gt;
&lt;p class="last"&gt;Please note we need to multiply one term from the polynomials with fewer terms by all the terms from
the polynomial with more terms. If we do the other way around, the runtime will be &lt;span class="math"&gt;\(O(MN^2)\)&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="question-3-4"&gt;
&lt;h3&gt;Question 3 &amp;amp; 4&lt;/h3&gt;
&lt;p&gt;I haven't coded up for question 3 because I want to wait for finishing sorting chapter. However, I can see how we
can get &lt;span class="math"&gt;\(O(MNlog(MN))\)&lt;/span&gt;. This solution is very similar to Question 1. We first multiply all terms out using
&lt;span class="math"&gt;\(O(MN)\)&lt;/span&gt;. Then, we sort resulting &lt;span class="math"&gt;\(MN\)&lt;/span&gt; terms by exponent. Then, we run through the linked list merging any
summing any terms with the same exponent (which will be contiguous). The sort takes &lt;span class="math"&gt;\(O(MNlog(MN))\)&lt;/span&gt; time.
The multipies and the merging of duplicates can be performed in &lt;span class="math"&gt;\(O(MN)\)&lt;/span&gt; time.
So, we have:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
O(MN) + O(MNlog(MN)) + O(MN) = O(MNlog(MN))
\end{equation*}
&lt;/div&gt;
&lt;p&gt;When we actually compare the runtime of three solutions, we can see 1st one is the worst among the three. However,
for 2nd one and 3rd one, the comparison result depends on the size of &lt;span class="math"&gt;\(M\)&lt;/span&gt; and &lt;span class="math"&gt;\(N\)&lt;/span&gt;. If &lt;span class="math"&gt;\(M\)&lt;/span&gt; and
&lt;span class="math"&gt;\(N\)&lt;/span&gt; are close in size, then &lt;span class="math"&gt;\(O(MNlog(MN))\approx O(MNlog(M^2))=O(MNlog(M))\)&lt;/span&gt;, which is better than &lt;span class="math"&gt;\(O(M^2N)\)&lt;/span&gt;.
However, if &lt;span class="math"&gt;\(M\)&lt;/span&gt; is very small in comparison to &lt;span class="math"&gt;\(N\)&lt;/span&gt;, then &lt;span class="math"&gt;\(M\)&lt;/span&gt; is less than &lt;span class="math"&gt;\(log(MN)\)&lt;/span&gt; and in this case,
2nd one is better than 3rd one.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;script type='text/javascript'&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML';
    mathjaxscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'AMS' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="Data Struct &amp; Algo"></category><category term="linked-list"></category><category term="maw"></category></entry><entry><title>Pelican Hack Day</title><link href="https://zhu45.org/posts/2016/Dec/17/pelican-hack-day/" rel="alternate"></link><published>2016-12-17T22:44:00+08:00</published><updated>2016-12-17T22:44:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-17:/posts/2016/Dec/17/pelican-hack-day/</id><summary type="html">&lt;p class="first last"&gt;Design log for Pelican website&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I have been using Sphinx since 2012 and I spend quite a amount of time to customize
my old Sphinx-based websites
(&lt;a class="reference external" href="https://zeyuanhu.wordpress.com/2016/11/24/under-construction-part-12/"&gt;This article revisits all my past website construction effort&lt;/a&gt;).
However, most of the time I'm tweaking the CSS and content organization of the site.
I never get my hands on a serious template customization. The reason is quite simple,
I have limited knowledge how Sphinx interact with Jinja template engine and Jinja
language itself just looks really bizzare to me.&lt;/p&gt;
&lt;p&gt;Now, since I start a new blog, I decide to give Jinja a chance and customize
&lt;a class="reference external" href="/archives/index.html"&gt;my archive page&lt;/a&gt; a little bit.&lt;/p&gt;
&lt;p&gt;Here is what I want my archive page to look like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Don't display post content. Only the title itself.&lt;/li&gt;
&lt;li&gt;Display archives by year and archives by tags within the same page at the same time.&lt;/li&gt;
&lt;li&gt;Display the number of posts for each year, and for each tag.&lt;/li&gt;
&lt;li&gt;Show the time only in "month.day.year". I don't need the hours and minutes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div class="section" id="first-iteration"&gt;
&lt;h2&gt;First Iteration&lt;/h2&gt;
&lt;p&gt;If you have read about &lt;a class="reference external" href="http://docs.getpelican.com/en/3.6.3/themes.html#templates-and-variables"&gt;Creating themes section in Pelican doc&lt;/a&gt;,
you will see that we have to work with &lt;tt class="docutils literal"&gt;archives.html&lt;/tt&gt;. Pelican will use the layout
specified in this file to generate our archive page.&lt;/p&gt;
&lt;p&gt;For the first iteration, my &lt;tt class="docutils literal"&gt;archives.html&lt;/tt&gt; looks something like this&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt; {% extends "base.html" %}
 {% block content %}
 &amp;lt;section id="content" class="body"&amp;gt;
 &amp;lt;h1&amp;gt;Archives for {{ SITENAME }}&amp;lt;/h1&amp;gt;

 {# based on http://stackoverflow.com/questions/12764291/jinja2-group-by-month-year #}

 {% for year, year_group in dates|groupby('date.year')|reverse %}
 {% for month, month_group in year_group|groupby('date.month')|reverse %}
     &amp;lt;h4 class="date"&amp;gt;{{ (month_group|first).date|strftime('%b %Y') }}&amp;lt;/h4&amp;gt;
     &amp;lt;div class="post archives"&amp;gt;
     &amp;lt;ul&amp;gt;
         {% for article in month_group %}
             &amp;lt;li&amp;gt;&amp;lt;a href="{{ SITEURL }}/{{ article.url }}"&amp;gt;{{ article.title }}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
         {% endfor %}
     &amp;lt;/ul&amp;gt;
     &amp;lt;/div&amp;gt;
 {% endfor %}
 {% endfor %}
 &amp;lt;/section&amp;gt;
 {% endblock %}
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Let's first take a look at what archive page we can get from this code.&lt;/p&gt;
&lt;img alt="pelican-hack-1 result" class="img-responsive" src="/images/pelican-hack-1.png"/&gt;
&lt;p&gt;Line[1],[2] illustrates how usually template file get organized. Usually, we create
a basic html file that specifies the layout of our site, which is &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt; in my case.
Then, we want to extends this basic html to tailor to different needs. Inside &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt;,
we will place a placeholder, which will be replaced by the content of each child html page:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{% block content %}
{% endblock %}
&lt;/pre&gt;
&lt;p&gt;In my case, I extends &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt; to make an archive page. The content enclosed between
&lt;tt class="docutils literal"&gt;{% block content %}&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;{% endblock %}&lt;/tt&gt; will replace the placeholder inside &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Line[4] &lt;tt class="docutils literal"&gt;{{ SITENAME }}&lt;/tt&gt; is very similar to shell expansion. We will expand the variable &lt;tt class="docutils literal"&gt;SITENAME&lt;/tt&gt;
with its content. &lt;tt class="docutils literal"&gt;SITENAME&lt;/tt&gt; is the same variable we specify in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; and the expanded
result will be the value we assign to &lt;tt class="docutils literal"&gt;SITENAME&lt;/tt&gt; variable in config file. In my case, the expansion
result will be "Tech Stuff".&lt;/p&gt;
&lt;p&gt;Starts from Line[8], things start to get interesting:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{% for year, year_group in dates|groupby('date.year')|reverse %}
...
{% endfor %}
&lt;/pre&gt;
&lt;p&gt;Jinja itself is based on Python. So, we can borrow some knowledge from our Python realm. As you can tell,
&lt;tt class="docutils literal"&gt;{% for ... %} ... {% endfor %}&lt;/tt&gt; is what for loop looks like in Jinja.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;dates&lt;/tt&gt; itself is a list of articles ordered by date, with each element is an &lt;em&gt;article&lt;/em&gt; object. Here is what
&lt;tt class="docutils literal"&gt;dates&lt;/tt&gt; looks like in my mind:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
dates = [ article1, article2, article2, ... ]
&lt;/pre&gt;
&lt;p&gt;and each &lt;em&gt;article&lt;/em&gt; looks like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
article = [ title, summary, author, date, ... ]
&lt;/pre&gt;
&lt;p&gt;Let's put the following code in our &lt;tt class="docutils literal"&gt;archives.html&lt;/tt&gt; to better understand the structure of &lt;tt class="docutils literal"&gt;dates&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{% for year in dates %}
&amp;lt;h1&amp;gt;{{ year }}&amp;lt;/h4&amp;gt;
{% endfor %}
&lt;/pre&gt;
&lt;p&gt;The output looks like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/Users/zeyuan/Documents/projects/linuxjedi.co.uk/content/blog/2016/12/17/pelican-hack.rst
/Users/zeyuan/Documents/projects/linuxjedi.co.uk/content/blog/2016/12/16/portability.rst
/Users/zeyuan/Documents/projects/linuxjedi.co.uk/content/blog/2016/12/03/maw-003.rst
/Users/zeyuan/Documents/projects/linuxjedi.co.uk/content/blog/2016/11/28/maw-002.rst
...
&lt;/pre&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;I would highly recommend to read through the
&lt;a class="reference external" href="http://docs.getpelican.com/en/3.6.3/themes.html#templates-and-variables"&gt;Creating themes section in Pelican doc&lt;/a&gt; page,
they describe those objects in word.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;groupby&lt;/tt&gt; is a &lt;a class="reference external" href="http://jinja.pocoo.org/docs/dev/templates/"&gt;Jinja filter which can group a sequence of objects by a common attribute&lt;/a&gt;
In our case, we want to group the info based on year. In other words, &lt;em&gt;article&lt;/em&gt; with the same year should be in the same group.
Let's experiment with the following code:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{% for year, year_group in dates|groupby('date.year') %}
    &amp;lt;h1&amp;gt;{{ year }} {{ year_group }}&amp;lt;/h4&amp;gt;
{% endfor %}
&lt;/pre&gt;
&lt;p&gt;The output looks like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
2015 []
2016 [, , , , , , ]
&lt;/pre&gt;
&lt;p&gt;Then, we apply &lt;tt class="docutils literal"&gt;reverse&lt;/tt&gt; filter to make &lt;tt class="docutils literal"&gt;2016&lt;/tt&gt; on top of &lt;tt class="docutils literal"&gt;2015&lt;/tt&gt;. The reset of the code shouldn't be hard to decode.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;&lt;tt class="docutils literal"&gt;|&lt;/tt&gt; is pipe, which is used to separate filters. It works like pipe in shell.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="count-posts"&gt;
&lt;h2&gt;Count posts&lt;/h2&gt;
&lt;p&gt;This is what my current archive page layout looks like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{% extends "base.html" %}
{% block content %}
&amp;lt;section id="content" class="body"&amp;gt;
&amp;lt;h1&amp;gt;Archives for {{ SITENAME }}&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;
&amp;lt;h2&amp;gt;Archives by year&amp;lt;/h2&amp;gt;

{% for year, numposts in articles|groupby('date.year') %}
&amp;lt;li&amp;gt;&amp;lt;a href="{{ SITEURL }}/archives/{{ year }}/period_archives.html"&amp;gt;{{ year }} ({{ numposts|count }})&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
{% endfor %}
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
&amp;lt;h2&amp;gt;Archives by tag&amp;lt;/h2&amp;gt;

{% for tag, articles in tags %}
&amp;lt;li&amp;gt;&amp;lt;a href="{{ SITEURL }}/tag/{{ tag }}.html"&amp;gt;{{ tag }} ({{ articles|count }})&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
{% endfor %}
&amp;lt;/p&amp;gt;
&amp;lt;/section&amp;gt;
{% endblock %}
&lt;/pre&gt;
&lt;p&gt;If you understand previous sections, this code chunk should have no problem to you. I should point out that &lt;tt class="docutils literal"&gt;count&lt;/tt&gt;
is the filter we use to count the number of &lt;em&gt;articles&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="the-rest"&gt;
&lt;h2&gt;The rest&lt;/h2&gt;
&lt;p&gt;For "Archive by year", I use another template "period_archives.html" to specify the layout. It looks pretty straightforward.
However, there is a problem takes me a while to figure out:&lt;/p&gt;
&lt;blockquote&gt;
When I click on certain year, I jump to the archive page for that year. In that year, I want to have
the page display "Archives for 2016". "2016" can be replaced based on the year I actually click initially.
This leads to a problem to me: how do I know which year the user click? In other words, how do I pass the information
to "period_archives.html"?&lt;/blockquote&gt;
&lt;p&gt;I couldn't find a nice way to solve this problem. Here is what I do:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{% for year, null in dates|groupby('date.year') %}
    &amp;lt;h1&amp;gt;Archives for {{ year }}&amp;lt;/h1&amp;gt;
{% endfor %}
&lt;/pre&gt;
&lt;p&gt;Since each articles under a certain year archive should have the same year value, I need to take a look at one of them
to find out the year value and put the value to the heading. However, I don't have to do this trick for tag. I can somehow
magically reference the value:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;h1&amp;gt;Archives by tag '{{ tag }}'&amp;lt;/h1&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Last point I want to point out is that you can define your own Jinja filter under &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
</content><category term="tools"></category><category term="pelican"></category><category term="Jinja"></category></entry><entry><title>Lesson Learned: Portability</title><link href="https://zhu45.org/posts/2016/Dec/16/lesson-learned-portability/" rel="alternate"></link><published>2016-12-16T23:20:00+08:00</published><updated>2016-12-16T23:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-16:/posts/2016/Dec/16/lesson-learned-portability/</id><summary type="html">&lt;p class="first last"&gt;Shell is not portable!&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Portability is a kind of issue that people always talk about in software engineering field.
I never have been through such problem on my own probably because I don't have to port my
stuff into different platforms. However, this is not the case anymore during the work.&lt;/p&gt;
&lt;p&gt;Recently, I revisit the first task I owned when I joined the team, which is to develop a lightweight
configuration tool to improve product usability. Lightweight is the key of this task as we originally
have a Java-based GUI setup tool involving lots of point &amp;amp; click. This solution is fairly unpopular among
our customers mainly because the program itself takes lots of space for DB2 image and it doesn't fit well
with his peers, which all are scripts that can be executed directly from shell.&lt;/p&gt;
&lt;p&gt;So, in my iteration, I decide to follow the format of majority of utility tools in DB2 image - using scripting language.
The language I choose is, unfortunately, Shell. The whole task goes amazingly well. With the help of my tool, product configuration
time is reduced by 75%. Everyone in my team loves it until someone decides to run it on AIX.&lt;/p&gt;
&lt;p&gt;The environment I develop the tool is SUSE with &lt;tt class="docutils literal"&gt;ksh&lt;/tt&gt; installed. The AIX that my colleague tries to test my tool on also has &lt;tt class="docutils literal"&gt;ksh&lt;/tt&gt; configured
but there are some quirky behavior difference on different platform.&lt;/p&gt;
&lt;p&gt;For instance, when I try to split an array, say &lt;tt class="docutils literal"&gt;tmp2&lt;/tt&gt; with delimiter &lt;tt class="docutils literal"&gt;:&lt;/tt&gt;, the following code works great on SUSE:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
saveIFS=$IFS
IFS=":"
local tmp2=($tmp) # split tmp with ":" and stored into tmp2 as array
IFS=$saveIFS
&lt;/pre&gt;
&lt;p&gt;However, on AIX, only the following way will work:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
#!/bin/sh
tmp=a:b:c:d
saveIFS=$IFS
IFS=":"
local tmp2
n=0
for i in $tmp; do tmp2[$n]=$i; ((n=n+1)); done
IFS=$saveIFS
echo ${tmp2[0]}
echo ${tmp2[1]}
echo ${tmp2[2]}
echo ${tmp2[3]}
&lt;/pre&gt;
&lt;p&gt;As you can see, I need a for loop to split the array on AIX.&lt;/p&gt;
&lt;p&gt;For another example, when I try to increment counter inside a loop, on SUSE,
I can do &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;((n++))&lt;/span&gt;&lt;/tt&gt; but on AIX, I need to do &lt;tt class="docutils literal"&gt;((n=n+1))&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;This makes me realize why most of our development scripts (i.e. to help build the source code)
use perl instead of shell. I have to rewrite the whole script in Perl.&lt;/p&gt;
&lt;p&gt;This is a very important lesson for a fresh college graduate by that time.&lt;/p&gt;
</content><category term="misc"></category><category term="software-engineering"></category><category term="shell"></category><category term="AIX"></category></entry><entry><title>Reverse Singly Linked List</title><link href="https://zhu45.org/posts/2016/Dec/03/reverse-singly-linked-list/" rel="alternate"></link><published>2016-12-03T20:34:00+08:00</published><updated>2016-12-03T20:34:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-12-03:/posts/2016/Dec/03/reverse-singly-linked-list/</id><summary type="html">&lt;p class="first last"&gt;MAW 3.12 question&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem"&gt;
&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;This problem is MAW 3.12:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;Write a nonrecursive procedure to reverse a singly linked list in O(N) time.&lt;/li&gt;
&lt;li&gt;Write a procedure to reverse a singly linked list in O(N) time using constant
extra space.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;Essentially, this is just one problem: reverse a singly linked list with various
constraints. There are a couple of ways doing so. All of them satisfy 3.12.a and
3.12.b&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Solution 2 &amp;amp; 3 are probably most people will expect, particularly during an
interview.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="solution-1"&gt;
&lt;h3&gt;Solution 1&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;reverseList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Solution 1 is pretty straightforward. We first create a new list. Then, we walk
through the original list and insert node we visit at the very beginning of the
new list. Once we finish the traversal of the original list, we return the new list.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;You can use a stack to reverse the list. This will require O(N) extra space.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This solution shows one of the reasons why we use a &lt;em&gt;header&lt;/em&gt; node or &lt;em&gt;dummy&lt;/em&gt; node
in our linked list implementation (instead of just use a pointer directly pointing
towards the first element in the list):&lt;/p&gt;
&lt;blockquote&gt;
Without the dummy node, there is no really obvious way to insert at the
front of the list.&lt;/blockquote&gt;
&lt;p&gt;This can be seen from Line[12]. Also, this routine has a return type &lt;tt class="docutils literal"&gt;List&lt;/tt&gt; instead of
&lt;tt class="docutils literal"&gt;void&lt;/tt&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The definition for using or not using &lt;em&gt;dummy&lt;/em&gt; node is the same. However,
implementation difference can be seen by observing how the program construct
a list: in my case, &lt;a class="reference external" href="https://zhu45.org/posts/2016/Nov/28/printlots/"&gt;initializeList&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;However, this solution wastes a ton of memory space and too many &lt;tt class="docutils literal"&gt;malloc&lt;/tt&gt; operations,
which basically duplicate the data. This is the place where the algorithm can be improved.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;reverseList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;// Remove element from old list.&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;// Insert element in new list.&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This solution has two interesting points:&lt;/p&gt;
&lt;ul class="last simple"&gt;
&lt;li&gt;It's obvious that it's correct: there are no corner cases to worry about
and both two-line operations are familiar to anyone who's manipulated a
linked list.&lt;/li&gt;
&lt;li&gt;It's pretty much identical to the Solution 2 (same number of temporary variables,
same assignments in slightly different order).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="solution-2"&gt;
&lt;h3&gt;Solution 2&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;reverseListIterative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyCurrent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;dummyNext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyCurrent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyNext&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyCurrent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyCurrent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyCurrent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyCurrent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyNext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyPrev&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;The 2nd solution is an iterative approach. The logic itself is quite straightforward.
But, please always remember we assume &lt;em&gt;dummy&lt;/em&gt; node exists. You can see both from
Line[4] and Line[15].&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;This actually not the solution I come up initially. My initial implementation
works but is not as nice as this one. You can check it out in my
&lt;a class="reference external" href="https://github.com/xxks-kkk/algo/blob/master/linkedList/linkedList.c"&gt;linkedList.c&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="solution-3"&gt;
&lt;h3&gt;Solution 3&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;reverseListRecursiveHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;reverseListRecursiveHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;reverseListRecursive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;reverseListRecursiveHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;This solution is a recursive solution. This causes me much time to think about
because we have a &lt;em&gt;dummy&lt;/em&gt; node to be taken care of. That's why I use a private
helper function. There is a couple important points to be noticed here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Use a static List variable &lt;tt class="docutils literal"&gt;P&lt;/tt&gt; is necessary because we need to keep track of
where is our first node after reverse (i.e. the last node in the original list
will become the first node after reversal). This is important because without
&lt;tt class="docutils literal"&gt;P&lt;/tt&gt;, we cannot access the first node because all the links are reversed and
we can no longer traverse the list from our &lt;em&gt;dummy&lt;/em&gt; node.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Inside &lt;tt class="docutils literal"&gt;reverseListRecursiveHelper&lt;/tt&gt;, I don't have to check if &lt;tt class="docutils literal"&gt;L&lt;/tt&gt; is &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt;
(You need to do this for no &lt;em&gt;dummy&lt;/em&gt; node implementation style). Essentially, this
is the base case where I got passed in an empty list. Since in our implementation,
&lt;em&gt;dummy&lt;/em&gt; node always exists even when the list is empty (check out &lt;tt class="docutils literal"&gt;deleteList&lt;/tt&gt; routine),
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;L-&amp;gt;Next&lt;/span&gt;&lt;/tt&gt; is always valid (we don't want to reference &lt;tt class="docutils literal"&gt;L&lt;/tt&gt;, which is &lt;tt class="docutils literal"&gt;NULL&lt;/tt&gt; already).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;We use a private function mainly because we have &lt;em&gt;dummy&lt;/em&gt; node in our implementation.
This is a special case that cannot be handled inside the recusive call. That's
also why the first data node in the original list is passed into the helper function.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="nf"&gt;reverseListRecursive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// empty list base case&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;// only one node (tail node) base case&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;reverseListRecursive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;The above code shows a perfect example why &lt;em&gt;dummy&lt;/em&gt; node case cannot be handled
in recursive call. This is because, when we do recursion, we always assume
there is &lt;em&gt;dummy&lt;/em&gt; node exists in the sub list we passed in. However, that is not
what our list acutally is. You can see why our recursion assumes the &lt;em&gt;dummy&lt;/em&gt; node exists by
reading Line[6] &amp;amp; Line[11] &amp;amp; Line[16].&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Data Struct &amp; Algo"></category><category term="linked-list"></category><category term="recursion"></category><category term="maw"></category></entry><entry><title>PrintLots</title><link href="https://zhu45.org/posts/2016/Nov/28/printlots/" rel="alternate"></link><published>2016-11-28T18:20:00+08:00</published><updated>2016-11-28T18:20:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-11-28:/posts/2016/Nov/28/printlots/</id><summary type="html">&lt;p class="first last"&gt;MAW 3.2&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="problem"&gt;
&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;Today, I finished the problem 3.2. The question is following:&lt;/p&gt;
&lt;blockquote&gt;
You are given a linked list, L, and another linked list, P, containing
integers sorted in ascending order. The operation &lt;tt class="docutils literal"&gt;PrintLots(L,P)&lt;/tt&gt;
will print the elements in L that are in positions specified by P.
For instance, if P = 1,3,4,6, the first, third, fourth, and sixth elements
in L are printed. Write the procedure &lt;tt class="docutils literal"&gt;PrintLots(L,P)&lt;/tt&gt;. You should
use the basic list operations. What is the running time of your procedure?&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable table  table-striped table-hover"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;
&lt;span class="normal"&gt;43&lt;/span&gt;
&lt;span class="normal"&gt;44&lt;/span&gt;
&lt;span class="normal"&gt;45&lt;/span&gt;
&lt;span class="normal"&gt;46&lt;/span&gt;
&lt;span class="normal"&gt;47&lt;/span&gt;
&lt;span class="normal"&gt;48&lt;/span&gt;
&lt;span class="normal"&gt;49&lt;/span&gt;
&lt;span class="normal"&gt;50&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;printLots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// creates dummy nodes to traverse the list&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;outofelement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;dummyP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyP&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;// if the idx is larger or equal to where the dummyL currently is&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;// we don't want to reset the dummyL to the very beginning of&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="c1"&gt;// the list L again to redo the traverse.&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;outofelement&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outofelement&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No element in position %d, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d, "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyL&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;outofelement&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;dummyP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummyP&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;The problem isn't hard to solve. However, to get things right, I need to develop several test cases.
Let's develop a solution that can handle more general situation. In other words, linked list, P, doesn't
necessarily contain integers sorted in ascending order. Here are test cases I developed:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
L: 23, 44, 45, 57, 89, -1

P:  1, 3, 4, 5          &amp;lt;--- normal case
    1, 3, 4, 6          &amp;lt;--- there is no sixth element in L
    1, 3, 4, 6, 7       &amp;lt;--- there is no sixth, seventh element in L
    6, 7, 3, 1          &amp;lt;--- there is no sixth, seventh element in L, but have third, first element
    6, 2, 7, 1          &amp;lt;--- a no element (6th) followed by a existing element (2nd)
   -9, 1, 3, 4          &amp;lt;--- negative integer from P appears at the beginning
    1, 2, 4, -10        &amp;lt;--- negative integer from P appears at the end
&lt;/pre&gt;
&lt;p&gt;The code presented above handles all these different situations. In addition, if the integers presented in P
are actually in ascending order, we want to take advantage of this piece of information. That's why we check
&lt;tt class="docutils literal"&gt;if (idx &amp;lt; i)&lt;/tt&gt;. We don't want to reset the traverse ptr (i.e. &lt;tt class="docutils literal"&gt;dummyL&lt;/tt&gt;) every single time. In other words,
if the number in P is actually ascending, we want to move the traver ptr from its current pos instead of reset.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="c-related"&gt;
&lt;h2&gt;C related&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;When I compose this post, I'm actually thinking of if &lt;tt class="docutils literal"&gt;if (idx &amp;gt;= 0)&lt;/tt&gt; is necessary. In other words, if C
supports the array element access using negative index, then we shouldn't use &lt;tt class="docutils literal"&gt;exit&lt;/tt&gt; to handle.
Luckily, C doesn't support this feature. In fact, C allows you to access the element using negative index,
but that is actually a out of bound access and C won't complain about this. However, whate exactly you get
is random. That is called "undefined behavior".&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Data Struct &amp; Algo"></category><category term="c"></category><category term="linked-list"></category><category term="maw"></category></entry><entry><title>Automatically publish Tinkerer bld output to GitHub with Travis CI</title><link href="https://zhu45.org/posts/2016/Nov/27/automatically-publish-tinkerer-bld-output-to-github-with-travis-ci/" rel="alternate"></link><published>2016-11-27T22:00:00+08:00</published><updated>2016-11-27T22:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-11-27:/posts/2016/Nov/27/automatically-publish-tinkerer-bld-output-to-github-with-travis-ci/</id><summary type="html">&lt;p class="first last"&gt;A taste of DevOps&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="perface"&gt;
&lt;h2&gt;Perface&lt;/h2&gt;
&lt;p&gt;I saw a comment from &lt;a class="reference external" href="https://www.notionsandnotes.org/tech/web-development/pelican-static-blog-setup.html"&gt;a web&lt;/a&gt;
that talks about auto deployment with Travis CI&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As an aside, you can also use GitHub Pages for hosting, which is free,
and then integrate it with Travis-CI to automatically publish the blog
(basically run pelican to generate the output and push the changes back online)
in order to decouple the actual writing of blog posts from the publishing part.&lt;/p&gt;
&lt;p&gt;The above also has the advantage of enabling a history of changes done
(both for the articles themselves and the output), as well as simplifying things
if you want to have guest posts and so on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That's the place where I start to explore Travis CI.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="travis-ci"&gt;
&lt;h2&gt;Travis CI&lt;/h2&gt;
&lt;p&gt;Travis CI part isn't hard to figure out. I referenced the following articles to get
me started with this great tool, particularly with Sphinx-doc:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/dwyl/learn-travis"&gt;learn-travis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/sphinx-doc/sphinx/blob/master/.travis.yml"&gt;Sphinx-doc repo .travis.yml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://coderwall.com/p/wws2uq/have-travis-ci-test-your-sphinx-docs"&gt;Have Travis-CI test your Sphinx docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The basic idea of Travis CI is quite simple. Once you commit something, it will
trigger Travis CI to clone your repository, and run the command you specified in
&lt;tt class="docutils literal"&gt;.travis.yml&lt;/tt&gt; and then it will tell you the result of this commit (i.e.
Whether you pass all the test specified in &lt;tt class="docutils literal"&gt;.travis.yml&lt;/tt&gt;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="work-with-tinkerer"&gt;
&lt;h2&gt;Work with Tinkerer&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Tinkerer is built upon Sphinx-doc. Any Sphinx-doc-ish tool should have similar
setup when work with Travis CI.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The setup for me is that I don't use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gh-pages&lt;/span&gt;&lt;/tt&gt;. Instead, I directly use &lt;tt class="docutils literal"&gt;master&lt;/tt&gt;
branch as the source for my github page. The reason is that Tinkerer will generate
&lt;tt class="docutils literal"&gt;index.html&lt;/tt&gt; directly inside root directory of the repo, which will redirect the
visit to &lt;tt class="docutils literal"&gt;index.html&lt;/tt&gt; under &lt;tt class="docutils literal"&gt;blog&lt;/tt&gt;. &lt;tt class="docutils literal"&gt;blog&lt;/tt&gt; is the default output directory.&lt;/p&gt;
&lt;p&gt;Here are the tutorials I referenced. However, all of them talk about working with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gh-pages&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://gist.github.com/domenic/ec8b0fc8ab45f39403dd"&gt;Auto-deploying built products to gh-pages with Travis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/"&gt;Automatically Publish Javadoc to GitHub Pages with Travis CI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first link above offers a framework of how you should get everything working and
the second link's bottom script offers some intuition.&lt;/p&gt;
&lt;p&gt;I'm not going to redo the work. I just want to point out something you need to be careful:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;DO NOT use personal token.&lt;/strong&gt; As mentioned by the first link, using a GitHub personal
access token offers the full access to all your git repo. That's a very high risk.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be Careful with Public/Private.&lt;/strong&gt; You need to use the Travis client to encrypt
the &lt;em&gt;private&lt;/em&gt; ssh key and upload the corresponding &lt;em&gt;public&lt;/em&gt; ssh key to your repository.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don't put passphrase for your ssh key.&lt;/strong&gt; If you do, Travis CI will ask for the passphrase
during the automation process, which will lead to build hang. If this happens, regenerate
the ssh key.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Be careful only upload your .enc file.&lt;/strong&gt; Don't upload your ssh private key to your repo.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="decode-the-script"&gt;
&lt;h2&gt;Decode the script&lt;/h2&gt;
&lt;div class="section" id="travis-yml"&gt;
&lt;h3&gt;.travis.yml&lt;/h3&gt;
&lt;p&gt;This is my &lt;a class="reference external" href="https://github.com/xxks-kkk/blog/blob/master/.travis.yml"&gt;.travis.yml&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
language: python
python:
  - "2.7"

install:
  - pip install tinkerer
  - pip install sphinxjp.themes.tinkerturquoise

script:
  - tinker -b

env:
  global:
  - ENCRYPTION_LABEL: "8c1ec1f6b778"
  - COMMIT_AUTHOR_EMAIL: "ferrishu3886@gmail.com"

after_success:
  - bash ./deploy.sh

notifications:
  email:
    recipients:
      - ferrishu3886@gmail.com
    on_success: change # option [alway|never|change]
    on_failure: always
&lt;/pre&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;install&lt;/tt&gt; section asks Travis CI to install the necessary packages to build our
doc.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;script&lt;/tt&gt; section contains our doc build command.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;env&lt;/tt&gt; section contains environment variables required for our &lt;tt class="docutils literal"&gt;deploy.sh&lt;/tt&gt;. They
are used to authorize a user on Travis CI to make &lt;tt class="docutils literal"&gt;git clone&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;git push&lt;/tt&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;after_success&lt;/tt&gt; tells Travis CI what to do once the &lt;tt class="docutils literal"&gt;script&lt;/tt&gt; section is done
successfully.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;notifications&lt;/tt&gt; customize the email notification.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="deploy-sh"&gt;
&lt;h3&gt;deploy.sh&lt;/h3&gt;
&lt;p&gt;For &lt;a class="reference external" href="https://github.com/xxks-kkk/blog/blob/master/deploy.sh"&gt;deploy.sh&lt;/a&gt; is easy to
understand if you take a look at the Travis CI log for a build.&lt;/p&gt;
&lt;p&gt;Travis CI first perform basic the environment setup. Then, it clones the git repository.
Next, it builds our doc. If the build is success, it executes our &lt;tt class="docutils literal"&gt;deploy.sh&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Inside &lt;tt class="docutils literal"&gt;deploy.sh&lt;/tt&gt;, the main idea is to first clone the same repo (i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;travis-dup&lt;/span&gt;&lt;/tt&gt;)
and copy the bld output pages (under &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;/xxks-kkk/blog/blog&lt;/span&gt;&lt;/tt&gt;) to the bld directory
of the same repo we just cloned (i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;travis-dup/blog&lt;/span&gt;&lt;/tt&gt;). If there is nothing
changed in the bld output pages, we exit. Else, we commit the changes and
use the authencation we just added (i.e. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;ssh-add&lt;/span&gt; travis&lt;/tt&gt;) and push the change to the repo.&lt;/p&gt;
&lt;p&gt;To keep it simpler, you can imagine Travis CI is a remote server that you can do anything you
want. Thus, we can let bld result to be pushed to our repo by asking user (i.e. travis) from
the remote server to do so.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="tools"></category><category term="github"></category><category term="travis-ci"></category></entry><entry><title>Generate a Linked List from a given array</title><link href="https://zhu45.org/posts/2016/Nov/27/generate-a-linked-list-from-a-given-array/" rel="alternate"></link><published>2016-11-27T19:38:00+08:00</published><updated>2016-11-27T19:38:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-11-27:/posts/2016/Nov/27/generate-a-linked-list-from-a-given-array/</id><summary type="html">&lt;p class="first last"&gt;Where MAW starts&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="perface"&gt;
&lt;h2&gt;Perface&lt;/h2&gt;
&lt;p&gt;Well, I'm starting to work through
&lt;a class="reference external" href="https://www.amazon.com/Data-Structures-Algorithm-Analysis-2nd/dp/0201498405"&gt;Data Structures and Algorithm Analysis in C (2nd edition)&lt;/a&gt;
(referenced as MAW in the following posts) a couple of months agao to serve several purposes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;to get enough familarity with C programming language&lt;/li&gt;
&lt;li&gt;to keep my computer science foundation knowledge fresh&lt;/li&gt;
&lt;li&gt;I'm interested in System-level programming and mastering C and C++ is a must.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I work on DB2 codebase but I don't play around the material I mentioned above a lot.
Things can get rusty pretty quickly. So, I need a way to keep fresh.&lt;/p&gt;
&lt;div class="admonition important"&gt;
&lt;p class="first admonition-title"&gt;Important&lt;/p&gt;
&lt;p class="last"&gt;All the source code relates to this book can be found on &lt;a class="reference external" href="https://github.com/xxks-kkk/algo"&gt;my git repo&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;For completeness and readability, here is my basic node declaraiton and definition.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// ET shorts for "ElementType"&lt;/span&gt;

&lt;span class="c1"&gt;// we always assume there is a dummy node at the very beginning&lt;/span&gt;
&lt;span class="c1"&gt;// of the list.&lt;/span&gt;
&lt;span class="cp"&gt;#ifndef _LINKED_LIST_H&lt;/span&gt;
&lt;span class="cp"&gt;#define _LINKED_LIST_H&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PtrToNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cp"&gt;#endif&lt;/span&gt;

&lt;span class="c1"&gt;// placed in the implementation file&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When I try to work through the linked list related questions in Chapter 2, the first thing
I need to do is to able to verify my solution. I need to figure out a way to quickly
generate a test linked list. So, that's what &lt;code&gt;List initializeList(ET A[], int arrayLen);&lt;/code&gt; for.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="nf"&gt;initializeNoHeaderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arrayLen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="p"&gt;;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arrayLen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;initializeNoHeaderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arrayLen&lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmpNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="nf"&gt;initializeList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arrayLen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Pos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;initializeNoHeaderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arrayLen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;initializeList&lt;/tt&gt; adds a dummy node and invokes &lt;tt class="docutils literal"&gt;initializeNoHeaderList&lt;/tt&gt; to
actually generate linked list from a given array. Inside &lt;tt class="docutils literal"&gt;initializeNoHeaderList&lt;/tt&gt;,
we use &lt;em&gt;recursion&lt;/em&gt; to generate the list from array.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;If we actually change &lt;code&gt;tmpNode-&amp;gt;Next = initializeNoHeaderList(A+1, arrayLen-1);&lt;/code&gt;
to &lt;code&gt;tmpNode-&amp;gt;Next = initializeList(A+1, arrayLen-1);&lt;/code&gt;, this can lead to
a list contains nodes alternate between actual data node and the dummy node.
(i.e. &lt;code&gt;ET test_arr[] = {23, 44, 45, 57, 89, -1};&lt;/code&gt; then the generated linked list
will be &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;23-&amp;gt;0-&amp;gt;44-&amp;gt;0-&amp;gt;45-&amp;gt;0-&amp;gt;57-&amp;gt;0-&amp;gt;89-&amp;gt;0-&amp;gt;-1-&amp;gt;0-&amp;gt;&lt;/span&gt;&lt;/tt&gt;)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="c-related"&gt;
&lt;h2&gt;C related&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;During the recursion call in &lt;tt class="docutils literal"&gt;initializeNoHeaderList&lt;/tt&gt;, we need to
pass in the subarray and the updated length. You can do so like I do
&lt;tt class="docutils literal"&gt;A+1&lt;/tt&gt; for the subarray (first element will be the second element of
the original array) and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;arrayLen-1&lt;/span&gt;&lt;/tt&gt; for the updated length.&lt;/p&gt;
&lt;p&gt;For some reason, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;arrayLen--&lt;/span&gt;&lt;/tt&gt; doesn't work here. If you do so, it
will lead to infinite recursion call and segmentation fault eventually.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;when array being passed to a function call, it actually got decayed into a
pointer pointing to the first element of array. So,
&lt;tt class="docutils literal"&gt;initializeNoHeaderList(ET &lt;span class="pre"&gt;A[],&lt;/span&gt; int arrayLen)&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;initializeNoHeaderList(ET *A, int arrayLen)&lt;/tt&gt;
are the same.&lt;/p&gt;
&lt;p class="last"&gt;Since when we pass in an array, essentially we pass in the pointer to the first element.
So, similarly, when we pass in the subarray, we can actually pass in the pointer pointing
to the first element of the subarray, which is the second element of the original array.
So, &lt;tt class="docutils literal"&gt;&amp;amp;A[1]&lt;/tt&gt; (A[1] gives us the element, and we need a pointer, so we use &lt;tt class="docutils literal"&gt;&amp;amp;&lt;/tt&gt;). Since,
&lt;tt class="docutils literal"&gt;array[index]&lt;/tt&gt; is the same as &lt;tt class="docutils literal"&gt;*(array+index)&lt;/tt&gt;, so &lt;tt class="docutils literal"&gt;&amp;amp;A[1]&lt;/tt&gt; is the same as
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;amp;*(A+1)&lt;/span&gt;&lt;/tt&gt;, which is &lt;tt class="docutils literal"&gt;A+1&lt;/tt&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;We use &lt;tt class="docutils literal"&gt;static&lt;/tt&gt; for &lt;tt class="docutils literal"&gt;initializeNoHeaderList&lt;/tt&gt; to make the function only visible
to the file we implement it (i.e. &lt;tt class="docutils literal"&gt;main.c&lt;/tt&gt;). This is the way we keep a helper function
private.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Data Struct &amp; Algo"></category><category term="c"></category><category term="linked-list"></category><category term="maw"></category></entry><entry><title>Hello World</title><link href="https://zhu45.org/posts/2016/Nov/23/hello-world/" rel="alternate"></link><published>2016-11-23T23:00:00+08:00</published><updated>2016-11-23T23:00:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2016-11-23:/posts/2016/Nov/23/hello-world/</id><summary type="html">&lt;p class="first last"&gt;Hello&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This blog will focus entirely on posts that involve either source code or
mathematical expression. If you are looking for my posts about life reflection,
book review, and many other non-technical posts, please check out &lt;a class="reference external" href="https://zeyuanhu.wordpress.com/"&gt;my blog on wordpress&lt;/a&gt;.&lt;/p&gt;
</content><category term="misc"></category><category term="meta"></category></entry><entry><title>Minimal Emacs Tutorial</title><link href="https://zhu45.org/posts/2015/Oct/18/minimal-emacs-tutorial/" rel="alternate"></link><published>2015-10-18T16:18:00+08:00</published><updated>2017-01-03T21:45:00+08:00</updated><author><name>Zeyuan Hu</name></author><id>tag:zhu45.org,2015-10-18:/posts/2015/Oct/18/minimal-emacs-tutorial/</id><summary type="html">&lt;p class="first last"&gt;Emacs quick reference&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="learn-about-emacs"&gt;
&lt;h2&gt;Learn about Emacs&lt;/h2&gt;
&lt;p&gt;Here I will cover some basic manipulation with text files using emacs. It should be enough to get started working with
emacs.&lt;/p&gt;
&lt;div class="section" id="terms-in-emacs"&gt;
&lt;h3&gt;Terms in Emacs&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Region: the highlighted area&lt;/li&gt;
&lt;li&gt;Kill: same as "cut"&lt;/li&gt;
&lt;li&gt;Yank: same as "paste"&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="emacs-key-notation"&gt;
&lt;h3&gt;Emacs Key Notation&lt;/h3&gt;
&lt;table border="1" class="table  table-striped docutils table-hover"&gt;
&lt;colgroup&gt;
&lt;col width="11%"/&gt;
&lt;col width="89%"/&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Prefix&lt;/th&gt;
&lt;th class="head"&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;C-&lt;/td&gt;
&lt;td&gt;(press and hold) the &lt;strong&gt;Control&lt;/strong&gt; key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;M-&lt;/td&gt;
&lt;td&gt;the Meta key (the &lt;strong&gt;Alt&lt;/strong&gt; key, on most keyboards)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;S-&lt;/td&gt;
&lt;td&gt;the &lt;strong&gt;Shift&lt;/strong&gt; key (ie. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;S-TAB&lt;/span&gt;&lt;/tt&gt; means Shift Tab)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;DEL&lt;/td&gt;
&lt;td&gt;the &lt;strong&gt;Backspace&lt;/strong&gt; key (not the Delete key).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;RET&lt;/td&gt;
&lt;td&gt;the Return or &lt;strong&gt;Enter&lt;/strong&gt; key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;SPC&lt;/td&gt;
&lt;td&gt;the &lt;strong&gt;Space bar&lt;/strong&gt; key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ESC&lt;/td&gt;
&lt;td&gt;the &lt;strong&gt;Escape&lt;/strong&gt; key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;TAB&lt;/td&gt;
&lt;td&gt;the &lt;strong&gt;TAB&lt;/strong&gt; key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ARR&lt;/td&gt;
&lt;td&gt;the arrow keys&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="common-usage"&gt;
&lt;h3&gt;Common Usage&lt;/h3&gt;
&lt;div class="section" id="system-operation"&gt;
&lt;h4&gt;System operation&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;C-g&lt;/strong&gt; keyboard-quit; cancels anything Emacs is executing. If you press
any key sequence wrongly, &lt;strong&gt;C-g&lt;/strong&gt; to cancel that incorrectly pressed key
sequence and start again.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-c&lt;/strong&gt; close emacs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x b&lt;/strong&gt; Open a promt to enter a buffer name&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-h f&lt;/strong&gt; Describe a function (i.e., &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-h&lt;/span&gt; f &lt;span class="pre"&gt;electric-indent-mode&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C-h&lt;/span&gt; f fboundp&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x ARR&lt;/strong&gt; quickly switch between buffers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-+&lt;/strong&gt; (&lt;strong&gt;C-x C--&lt;/strong&gt;) increase (decrease) font size&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="file-editing"&gt;
&lt;h4&gt;File Editing&lt;/h4&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;ul class="last simple"&gt;
&lt;li&gt;You need to set mark before you can use region operation. To know more about
&lt;a class="reference external" href="https://www.cs.colorado.edu/~main/cs1300-old/cs1300/doc/emacs/emacs_13.html"&gt;The Mark and Region&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;To move or copy a region of text in emacs, you must first "mark" it, then kill or copy the marked text, move the cu
rsor to the desired location, and restore the killed or copied text. A region of text is defined by marking one end         of it, then moving the cursor to the other end.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;C-@&lt;/strong&gt; Set the mark here&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-SPC&lt;/strong&gt; Set the mark where point is&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x-h&lt;/strong&gt; Select the whole text&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-w&lt;/strong&gt; kill the region&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-d&lt;/strong&gt; kill forward to the end of the next word (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;kill-word&lt;/span&gt;&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-y&lt;/strong&gt; yank the region&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-w&lt;/strong&gt; copy the region&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-k&lt;/strong&gt; kill the whole line (note you need to put the cursor at the very beginning of the line)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;To copy text, kill it, yank it back immediately (so it's as if you haven't killed it, except it's now in the kill ring
), move elsewhere and yank it back again.&lt;/p&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;C-x C-s&lt;/strong&gt; save file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-v RET&lt;/strong&gt; reload a file (alternative way is &lt;strong&gt;M-x revert-buffer&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-/&lt;/strong&gt; (&lt;strong&gt;C-x u&lt;/strong&gt;) undo&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-r&lt;/strong&gt; invoke backward search (type search word thereafter. Use &lt;strong&gt;C-r&lt;/strong&gt;
to repeatedly travel through the matches backward)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-s&lt;/strong&gt; similar to &lt;strong&gt;C-r&lt;/strong&gt; but search forward&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x r t&lt;/strong&gt; insert words to multiple lines highlighted (the same thing you typed will be entered on all the lines you've
selected)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-x clipboard-yank&lt;/strong&gt; paste the clipboard text to emacs (useful when using emacs GUI)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-x clipboard-kill-region&lt;/strong&gt; paste emacs text to clipboard&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="cursor-movement"&gt;
&lt;h4&gt;Cursor Movement&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;ESC-&amp;lt;&lt;/strong&gt; go to the beginning of the file&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ESC-a&lt;/strong&gt; go to beginning of the sentence&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ESC-e&lt;/strong&gt; go to end of the sentence&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-a&lt;/strong&gt; go to beginning of the line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-e&lt;/strong&gt; go to the end of the line&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-x goto-line&lt;/strong&gt; go to the line specified&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-e RET&lt;/strong&gt; simulate &lt;tt class="docutils literal"&gt;o&lt;/tt&gt; in vi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-a RET&lt;/strong&gt; simulate &lt;tt class="docutils literal"&gt;O&lt;/tt&gt; in vi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-Up&lt;/strong&gt; go to the cursor location before a chunk of test pasted&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-v&lt;/strong&gt; page down&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-v&lt;/strong&gt; page up&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="searching-and-replacing"&gt;
&lt;h4&gt;Searching and Replacing&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;ESC-%&lt;/strong&gt; (query-replace) - ask before replacing each OLD STRING with NEW STRING.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Type &lt;tt class="docutils literal"&gt;y&lt;/tt&gt; to replace this one and go to the next one&lt;/li&gt;
&lt;li&gt;Type &lt;tt class="docutils literal"&gt;n&lt;/tt&gt; to skip to next without replacing&lt;/li&gt;
&lt;li&gt;Type &lt;tt class="docutils literal"&gt;!&lt;/tt&gt; to replace this one and remaining replacements without asking&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Query-Replace.html"&gt;See more options in GNU manual&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;Esc-x replace-string&lt;/strong&gt; replace all occurrences of OLD STRING with NEW STRING.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;&lt;strong&gt;ESC-x list-matching-lines&lt;/strong&gt; lists all the lines matching your pattern in a separate buffer, along with their numbers. Use "ESC-x goto-line" to go to the occurrence you're interested in.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="manage-split-windows"&gt;
&lt;h4&gt;Manage Split Windows&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;C-x 2&lt;/strong&gt; split-window-below&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x 3&lt;/strong&gt; split-window-right&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x 1&lt;/strong&gt; delete-other-windows (unsplit all)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x 0&lt;/strong&gt; delete-window  (remove current pane)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x o&lt;/strong&gt; other-window (cycles among the opening buffers)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="file-management-dired-mode"&gt;
&lt;h4&gt;File Management (dired mode)&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;M-x dired&lt;/strong&gt; start view directory&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;^&lt;/strong&gt; go to parent dir&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;g&lt;/strong&gt; refresh dir listing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;q&lt;/strong&gt; Quit dired mode (buffer still exists)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RET&lt;/strong&gt; Open the file or directory (this will open with another buffer). If you want to stick with one buffer, use &lt;strong&gt;a&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;o&lt;/strong&gt; Open file in another window (move cursor to that window as well)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-o&lt;/strong&gt; Open file in another window but stay on dired buffer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;+&lt;/strong&gt; create new dir&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x C-f&lt;/strong&gt; Create a new file (yes, the command is the same as opening a new file in non-dired mode)&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="other"&gt;
&lt;h4&gt;Other&lt;/h4&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;M-x whitespace-mode&lt;/strong&gt; allows you to explicitly see white-space, tab, newline. Especially useful when work
with python.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;M-x sort-lines&lt;/strong&gt; allows you to sort the marked region alphabetically. Especially useful when work with lots of Java
&lt;tt class="docutils literal"&gt;import&lt;/tt&gt; or C &lt;tt class="docutils literal"&gt;#include&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C-x l&lt;/strong&gt; count number of the lines for the file; give the current line number; list how many lines left.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="howtos"&gt;
&lt;h3&gt;HowTos&lt;/h3&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Parent shell&lt;/p&gt;
&lt;p&gt;When running Emacs in a terminal, you can press &lt;strong&gt;C-z&lt;/strong&gt;, type the shell command and then resume Emacs with &lt;strong&gt;fg&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;How can I get Emacs to reload all my definitions that I have updated in .emacs without restarting Emacs?&lt;/p&gt;
&lt;p&gt;You can use the command load-file (&lt;strong&gt;M-x load-file&lt;/strong&gt;, then press return twice to accept the default filename, which         is the current file being edited).&lt;/p&gt;
&lt;p&gt;You can also just move the point to the end of any sexp and press &lt;strong&gt;C-x C-e&lt;/strong&gt; to execute just that sexp. Usually it'
s not necessary to reload the whole file if you're just changing a line or two.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;M-x eval-buffer&lt;/strong&gt; immediately evaluates all code in the buffer, its the quickest method, if your &lt;tt class="docutils literal"&gt;.emacs&lt;/tt&gt; is
idempotent.&lt;/p&gt;
&lt;p&gt;You can usually just re-evaluate the changed region. Mark the region of ~/.emacs that you've changed, and then use
&lt;strong&gt;M-x eval-region RET&lt;/strong&gt;. This is often safer than re-evaluating the entire file since it's easy to write a .emacs
file that doesn't work quite right after being loaded twice.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Shift multiple lines with TAB&lt;/p&gt;
&lt;p&gt;Select multiply lines, then type &lt;strong&gt;C-u 8 C-x Tab&lt;/strong&gt;, it will indent the region by 8 spaces. &lt;strong&gt;C-u -4 C-x Tab&lt;/strong&gt; will un-indent by 4 spaces.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Switch between windows when one windows open with term&lt;/p&gt;
&lt;p&gt;If you open two windows, and one window open a term (ie. &lt;strong&gt;M-x term&lt;/strong&gt;), now you want to switch back to another
window. You may find out "C-x o" may no longer work. In this case, you may want to use &lt;strong&gt;C-c o&lt;/strong&gt; to switch to next
window from term&lt;/p&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Comment out multiple region&lt;/p&gt;
&lt;p&gt;Comment out multiple lines. Highlight the region and then &lt;strong&gt;M-x comment-region&lt;/strong&gt;. To undo the comment,
&lt;strong&gt;M-x uncomment-region&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Error during download request: Not Found&lt;/p&gt;
&lt;p&gt;Happened when you try to install a package (M-x package-install). &lt;strong&gt;M-x package-refresh-contents&lt;/strong&gt; to rescue.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Editing multiple lines at the same time&lt;/p&gt;
&lt;p&gt;suppose I have the following chunk of code that I want to edit:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
printf "%s=%s\n" "Database" "bool_db"
printf "%s=%s\n" "Username"  "admin"
printf "%s=%s\n" "Password"  "password"
printf "%s=%s\n" "ReadOnly"  "false"
printf "%s=%s\n" "ShowSystemTables" "false"
printf "%s=%s\n" "LegacySQLTables" "false"
printf "%s=%s\n" "LoginTimeout" "0"
&lt;/pre&gt;
&lt;p&gt;and I want to remove all &lt;tt class="docutils literal"&gt;printf &lt;span class="pre"&gt;"%s=%s\n"&lt;/span&gt;&lt;/tt&gt; in each line. I can do the following:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Mark the beginning of the region and invoke &lt;strong&gt;M-x rectangle-mark-mode&lt;/strong&gt; (or &lt;strong&gt;C-x SPC&lt;/strong&gt;) and select all the &lt;tt class="docutils literal"&gt;printf &lt;span class="pre"&gt;"%s=%s\n"&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Delete them by &lt;strong&gt;M-x kill-region&lt;/strong&gt; (or &lt;strong&gt;C-x r k&lt;/strong&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Instead of delete, you can use &lt;strong&gt;C-x r t string RET&lt;/strong&gt; to replace rectangle contents with &lt;em&gt;string&lt;/em&gt; con each line.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Turn on the line number on the left hand side&lt;/p&gt;
&lt;p&gt;I find this is particularly useful when I work with gdb in emacs. It can be done with &lt;strong&gt;M-x linum-mode&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="resources"&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;p&gt;Personally reference them a lot. But there are ton online through google.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://mally.stanford.edu/~sr/computing/emacs.html"&gt;Stanford emacs basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://ergoemacs.org/emacs/emacs_find_replace.html"&gt;Xah Emacs Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/caiorss/Emacs-Elisp-Programming"&gt;Emacs-Elisp-Programming&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="emacs-configuration"&gt;
&lt;h2&gt;Emacs Configuration&lt;/h2&gt;
&lt;p&gt;This is my &lt;a class="reference external" href="https://github.com/xxks-kkk/emacs-config"&gt;personal emacs configuration&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</content><category term="tools"></category><category term="emacs"></category></entry></feed>