`2019-11-13`

*
hardware, esrille, cherry mx

Over three years ago, I wrote a post describing the Esrille Nisse keyboard. This post is a reflection on the keyboard, more than 3 years later.

Ultimately I settled on a different layout than the one described in the old blog post. This was a result of many hands-on trial-and-error sessions over a period of weeks which turned into many months. In my old post I described writing a program to help find the optimal layout. This proved very difficult in practice, because encoding the optimization rules turned out to be non-trivial. One aspect that was particularly difficult was that the actualy physical shape of my own fingers played a part (some fingers were not as versatile as others, for example the pinky finger, and so the key-distance for certain fingers had to have different “weights”, and this was too much to translate into code).

Anyway, I read this post by Peter Norvig forwards and backwards, and used the values there to guide the design of my layout. One big realization after actual usage was that I could not let go of the QWERTY `hjkl`

keys on the home row. There was just so much muscle memory built into these four keys (the only other key I could not let go of was the spacebar key that I used my left thumb for), that I had to “fix” them on the layout first. I then focused on getting the commonly-used keys right.

All that being said, here is my current layout.

```
LEFT-SIDE RIGHT-SIDE
---------------------------
□ □ □ □ □ □ □ □ □ □ □ □
□ □ 0 □ □ □ □ 0 □ 1
□ □ □ y o p z 1 2 f d t r □ □ □
2 / a i e u w ; " h j k l n 4 : <--- Home row
3 . x q v ' b m g c s 3
8 5 6 7 4 5 , 6 7 8 <--------- Thumb row
Left-side legend
0) Escape
1) PgDn
2) Enter
3) Shift
4) Control
5) Super (Windows key)
6) Space
7) Caps Lock (remapped with xmodmap to Hyper key)
8) Right Alt (aka "AltGr" for US International Layout)
Right-side legend
0) Tab
1) Delete
2) PgUp
3) Shift
4) Backspace
5) FN2
6) FN
7) Alt
8) Right Alt (aka "AltGr" for US International Layout)
```

The main thing to note is the reduced number of keys that are mapped at all. I like this aspect a lot (not having to move my fingers around much at all) — I never have to reach for a particular key because everything is just so close.

I also dedicated a key just for the colon symbol (as a “Shift + semicolon” macro), because it comes up often enough in programming.

I should also note that the function keys (F1-F12) are situated on the topmost row, left-to-right. I just didn’t bother adding them to the legend because of symbol space constraints.

FN layer.

```
LEFT-SIDE RIGHT-SIDE
---------------------------
□ □ □ □ □ □ □ □ □ □ □ □
□ □ a □ □ □ □ □ □ □
□ □ □ 7 8 9 □ □ □ □ \ _ = □ □ □
□ □ 0 4 5 6 □ b b - { ( ) } a : <--- Home row
c . 1 2 3 ` □ [ < > ] c
□ □ □ □ □ □ □ □ □ □ <--------- Thumb row
Left-side legend
a) ~/ (a macro that inserts the string "~/")
b) End
c) Shift
Right-side legend
a) Backspace
b) Home
c) Shift
```

The FN layer has the majority of the punctuation keys I need. You might notice that some symbols like `!@#$&*^`

are not in here. This is because the numeral keys on the left side are actually the same numeral keys on the top row (**not** the Numpad) of a typical QWERTY layout. This means that I can just press FN+Shift to get these keys. This is the main trick that allowed me to reduce the number of keys used overall.

The “~/” macro in the left side is particularly useful as well.

FN2 layer.

```
LEFT-SIDE RIGHT-SIDE
---------------------------
□ □ □ □ □ □ □ □ □ □ □ □
□ □ □ □ □ □ □ □ □ □
□ □ □ □ □ □ □ □ □ □ □ □ □ □ □ □
□ □ □ □ □ □ □ □ □ a b c d □ □ □ <--- Home row
□ □ □ □ □ □ □ □ □ □ e □
□ □ □ □ □ □ □ □ □ □ <--------- Thumb row
Right-side legend
a) Left Arrow
b) Down Arrow
c) Up Arrow
d) Right Arrow
e) Shift + Insert macro (for pasting X primary buffer)
```

This layer is mostly empty, but it is used surprisingly frequently. I really like how the arrow keys line up with my `hjkl`

keys in the main layer.

For the latest changes to my layout, check out this repo.

It took me roughly 3 months of everyday use to get somewhat familiar with the layout, and probably another month or two to reach upwards of 60wpm.

It was painstakingly slow at first (it felt a lot like learning how to type all over again), but still “fun” because I noticed that I was getting better with time.

I think these days (after having used this keyboard every day for both my home and work PCs (yes, I have two of these!)) I can go higher than 60wpm.

Suffice it to say that there is never a time when I think “oh, I wish I could type faster” on this layout. My speed on this keyboard is about on par as with my old typing speed on QWERTY.

My typing speed on the old QWERTY layout hasn’t really changed. I still have to use it for when I use the keyboard on laptops. And surprisingly, my brain knows to “switch” to QWERTY when I’m typing on there — granted, this instinct took some time to kick in.

Yes.

The biggest thing I love about this layout is that I don’t have to move my right hand around when reaching for the typical “hard” keys on QWERTY (such as `[]{}`). I rarely (if ever) have typos when typing punctuation keys. The numeral keys being just underneath my left hand in a different layer is nice, too.

There are some “downsides” though in everyday life:

- it’s hard to play games because the key mappings are usually designed for QWERTY;
- when I make typos using this layout, they look rather unusual from a “QWERTY” perspective (as a contrived example, I might type “yen” instead of “yes” because the “n” and “s” keys are next to each other on my layout)

I don’t really play games that much though, and when I do I am usually on the separate gaming PC that just use a regular QWERTY layout so it’s not really a negative.

I guess the biggest downside of all is that the keyboard form factor on the Nisse is one-of-a-kind on the planet. If Esrille goes under, I would be worried about taking very good care of my keyboards in case one of the components breaks for whatever reason. I imagine that at that point, I would have to just create my own keyboard or make do with a shabby imitation using ErgoDox or some other form factor. I sincerely hope that that day never comes…!

Happy hacking!

]]>`2019-11-11`

*
status

It’s been another year since my last blog post!

I’m still happily employed at Google.

I’m still working on this project. It is hard because I’m trying to create real repositories and situations that the reader should be able to check out and follow along. Still, I should be able to finish this next year.

I’ve started dabbling in Clojure, Rust, and Elixir. This list is not the same list of programming languages in my last post (which mentioned Shen, Rust, Erlang, Idris, and Factor), but it’s something to chew on for quite some time.

I will post again when the Git book is ready. Stay tuned!

]]>`2018-11-11`

*
status

It’s been a year since my last blog post. Many things have happened since that time.

Below are some of the more interesting items.

I got laid off at IMVU in September 2017. It was a difficult time for me as I had become good friends with the people there. After almost 2 months of searching for jobs, I somehow managed to land a job at Google! My title is Release Engineer. I’ve been there almost a year now and I am still happy and excited to work there.

I started learning Golang a few months ago, because, I felt that this is the best time to learn it (while I’m employed by Google). I haven’t really done any of the advanced things yet, but I like how the language tries really hard to keep the syntax simple. It’s a lot like C in that regard.

The only pain point in Go for me is the packaging/installation system. The whole opintionated $GOPATH thing just feels a bit clunky because of the shared folder namespace with other projects. But I guess that’s unavoidable in any language’s ecosystem.

I started writing a short (informal) book on Git. I am using LuaTeX to write it; I started in March 2018 but have yet to cross the 1/2 way mark. Hopefully I’ll get it done before March 2019 rolls around.

Back in 2016’s status update I said that I still planned to finish the Haskell book I was working on. That project is definitely dead. One reason is that due to the rising popularity of the language, I feel that other people have already said what I had meant to say in my book.

I’ve grown interested in these languages because well, I feel like they are important. My hope is to find some interesting problems that can be solved idiomatically in each language. That might take years, but, it is my hope that in the future I’ll be able to write about these languages.

Apparently HTTPS support for custom domains on Github have been a thing since earlier this year. I never got around to it but thanks to this post I finally enabled it.

]]>`2017-11-11`

*
linux, git

A while ago I discovered that there is a manpage for the ASCII character set. It got a bunch of upvotes, and since then I wondered what other manpages were worth knowing about. Below is a small table of manpages that I found interesting.

Manpage | Description |
---|---|

`ascii(7)` |
the ASCII character set (in octal, decimal, and hex) |

`units(7)` |
megabytes vs mebibytes, etc. |

`hier(7)` |
traditional filesystem hierarchy (e.g., `/bin` vs `/usr/bin` ) |

`file-hierarchy(7)` |
(systemd) filesystem hierarchy |

`operator(7)` |
C operator precedence rules (listed in descending order) |

`console_codes(4)` |
Linux console escape and control sequences |

`terminal-colors.d(5)` |
among other things, ANSI color sequences |

`boot(7)` |
UNIX System V Release 4 bootup process |

`daemon(7)` |
(systemd) how to write/package daemons |

`proc(5)` |
proc filesystem (`/proc` ) |

`ip(7)` |
Linux IPv4 protocol implementation (a bit low-level, but still useful) |

`ipv6(7)` |
Linux IPv6 protocol implementation |

`socket(7)` |
Linux socket interface |

`unix(7)` |
UNIX domain sockets |

`fifo(7)` |
named pipes |

Note that you need to run

```
sudo mandb
```

to be able to invoke `apropos <SEARCH_TERM>`

or `man -k <SEARCH_TERM>`

(`man -k`

is equivalent to `apropos`

— see `man(1)`

).

You probably knew already that Git has many manpages dedicated to each of its subcommands, such as `git-clone(1)`

or `git-commit(1)`

, but did you know that it also comes with a suite of tutorials? Behold!

Manpage | Description |
---|---|

`giteveryday(7)` |
the top ~20 useful git commands you should know |

`gitglossary(7)` |
a glossary of all git concepts (blob object, working tree, etc.) |

`gittutorial(7)` |
a high-level view of using git |

`gittutorial-2(7)` |
explains the object database and index file (git architecture internals) |

`gitcore-tutorial(7)` |
like `gittutorial-2(7)` , but much more detailed |

`gitworkflows(7)` |
recommended workflows, esp. branching strategies for maintainers |

Happy hacking!

]]>`2017-05-13`

*
math

In the very first chapter of the book *Concrete Mathematics* 2ed there is a discussion about the Tower of Hanoi. This post is a distillation of that discussion.

There are 3 rods, with 8 discs (with holes) resting on one rod; the discs are sorted in size like a pyramid, with the smallest disc on top. We want to move all discs to another rod, but with the following rules: (1) a move consists of moving a single disc onto a rod; (2) you may never place a bigger disc on top of a smaller one. A question arises — **how many steps are required to move the entire tower of disks onto another rod?**

First consider the simplest case, without any discs. Because there are no discs to move, we cannot make any moves, and so the number of steps required is 0. We can write this as

\[ S_0 = 0 \]

with \(S\) meaning the number of steps and the subscript representing the number of discs in the tower.

Now let’s consider how the problem scales. With 1 disc, the answer is a single step since the one disc is itself the entire tower. With 2 discs, the answer is three steps — one step to move the top (small) disc to another rod, one step to move the big disc to the destination rod, and lastly one step to move the small disc on top of the big disc. With 3 discs, the answer is seven steps — the insight here is that we treat the top two discs exactly the same as the previous problem; so we need 3 moves to move the top two to another rod, then one move to move the biggest disc to the destination rod, then again 3 moves to move the 2-disc sub-tower to the destination rod.

The example with 3 discs is quite telling. We can use the insights gained there to set an upper bound to the number of steps required for the general case of \(n\) discs; if we take more steps than this upper bound, we would know that we made mistakes. For a tower of size \(n\), we require \(S_{n - 1}\) steps to move all discs except the biggest one, then move the biggest disc, then move the sub-tower on top of that disc with (again) \(S_{n - 1}\) steps. So the upper bound is

\[ \begin{equation} \label{eq:recurrence} S_n = \begin{cases} 0 & \text{if } n = 0 \\ 2 * (S_{n - 1}) + 1 & \text{if } n > 0. \end{cases} \end{equation} \]

If that’s the upper bound, then is there a separate formula for the *lower bound* (optimal solution)? Nope! It’s because there must come a time in solving the puzzle where we move the biggest disc to the destination rod. To get to the biggest disc, we must have moved all discs on top of it to another rod (the sub-tower); and, after having moved the biggest disc, we must move this sub-tower back on top of that rod (back onto the biggest disc). Because of these constraints stemming the definition of the puzzle itself, we know that for \(n\) > 0 we must take *at least* \(2 * (S_{n - 1}) + 1\) steps.

The upper and lower bounds agree in their formulation, and this formulation (Equation \(\ref{eq:recurrence}\)) is our recurrence. In mathematics, a recurrence relation is basically a recursively-defined equation, where a *base case* in the recurrence defines the starting point. In Equation \(\ref{eq:recurrence}\), the base case is \(n = 0\); for \(n > 0\), we define the number of steps required in a recursive manner.

In our discussion of finding the upper and lower bounds, there were two key concepts — the need to move the biggest disc, and the need to move the sub-tower twice (before and after moving the biggest disc). Our recurrence clearly agrees with these two concepts. The “\(+ 1\)” in the non-base case is the step of moving the biggest disc, whereas the \(2 * (S_{n - 1})\) is the number of steps required to move the sub-tower *twice*.

Recurrences are great, but they are painful to compute. For example, it’s not immediately clear what \(S_{11}\) or \(S_{54}\) evaluates to. It would be really nice if we could avoid defining \(S_n\) recursively.

And this is where math meets science. In the scientific method, we have to come up with a hypothesis and then test that hypothesis with one or more experiments. We can do the same thing here by trying to guess the solution to the recurrence.

For one thing, we know that \(S_n\) grows as \(n\) grows (it will never be the case that \(S_n\) somehow plateaus or decreases down the road). The more discs there are, the more work we have to do, right? So let’s look at small cases to see how the numbers grow, and see if there is a pattern to the growth rate of \(S_n\).

\(n\) | \(S_n\) |
---|---|

0 | 0 |

1 | 1 |

2 | 3 |

3 | 7 |

4 | 15 |

5 | 31 |

6 | 63 |

7 | 127 |

8 | 255 |

We don’t have to actually simulate the puzzle to derive these values; using the recurrence Equation \(\ref{eq:recurrence}\) we start off from the first row (the base case) and then calculate our way down, reusing \(S_n\) from the previous row as \(S_{n - 1}\). ^{1}

Anyway, the values of \(S_n\) sure look familiar — especially if we use base 2.

\(n\) | binary(\(S_n\)) |
---|---|

0 | \(0_2\) |

1 | \(1_2\) |

2 | \(11_2\) |

3 | \(111_2\) |

4 | \(1111_2\) |

5 | \(11111_2\) |

6 | \(111111_2\) |

7 | \(1111111_2\) |

8 | \(11111111_2\) |

It looks like our recurrence simplifies to just

\[ \begin{equation} \label{eq:solution} S_n = 2^n - 1 \quad \text{for } n \geq 0, \end{equation} \]

except it is no longer a recurrence as there is no need to define a base case. We’ll call it a *solution* to the recurrence.

Although the empirical evidence looks very good, we have not formally proved that the solution (Equation \(\ref{eq:solution}\)) holds for *all* \(n\). It’s one thing to say that something is true for all *observed* cases (scientific experiment), and quite another to say that something is true for *all* cases (mathematical proof).

Can we prove it? Yes! Fortunately for us, Equation \(\ref{eq:recurrence}\) lends itself to proof by induction. Induction requires you to first prove some number \(k_0\) as a starting point (the base case) using some proposition \(P\). Then you prove that \(P\) holds for \(k + 1\) (the next number); i.e., show that going from \(k\) to \(k + 1\) does not change \(P\). This is the *inductive step*. In this way, we prove the “totality” of \(P\) as it applies to all numbers in the range \([k_0, k_{m}]\) and we are done. ^{2}

Here we want to prove that Equation \(\ref{eq:solution}\) holds for all \(n\) (all natural numbers). ^{3} For this proof let’s rewrite Equation \(\ref{eq:solution}\) to use \(k\) instead of \(n\):

\[ \begin{equation} \label{eq:proposition} S_k = 2^k - 1 \quad \text{for } k \geq 0. \end{equation} \]

Equation \(\ref{eq:proposition}\) is our proposition \(P\). The base case is easy enough to prove: \(S_0 = 0\) because there are no disks to move. For the inductive step, we use the non-base part of our recurrence from Equation \(\ref{eq:recurrence}\) to get

\[ \begin{align} S_k &= 2 * (S_{k - 1}) + 1 \label{eq:induct1} \end{align} \]

and rewrite it in terms of \(k + 1\):

\[ \begin{align} S_{k + 1} &= 2 * (S_{k}) + 1. \label{eq:induct2} \end{align} \]

Now the critical part: we replace \(S_k\) with Equation \(\ref{eq:proposition}\) (our proposition), because we assume that our proposition is true for all steps up to \(k\) (but not \(k + 1\), which is what we’re trying to prove):

\[ \begin{align} S_{k + 1} &= 2 * (2^k - 1) + 1. \end{align} \]

In case you forgot algebra, \(2 * 2^k = 2^1 * 2^k = 2^{k + 1}\) and we can use this to simplify our equation.

\[ \begin{align} S_{k + 1} &= 2 * (2^k - 1) + 1\\ &= [2 * (2^k - 1)] + 1\\ &= [(2 * 2^k - 2)] + 1\\ &= (2^{k + 1} - 2) + 1\\ &= 2^{k + 1} - 1 \label{eq:induct3}. \end{align} \]

And now we can see that Equation \(\ref{eq:induct3}\) (our “evolved” proposition \(P\), if you will) is the same as our solution (Equation \(\ref{eq:solution}\)), even though we increased \(k\) to \(k + 1\)! This is because simple substitution allows us to replace “\(k + 1\)” with “\(n\)”. We have completed our proof by induction. ^{4}

The book goes on to offer an alternate recurrence to Equation \(\ref{eq:recurrence}\), by adding 1 to both sides:

\[ \begin{align} (S_n) + 1 &= \begin{cases} 0 + 1 & \text{if } n = 0 \\ 2 * (S_{n - 1}) + 1 + 1 & \text{if } n > 0 \\ \end{cases}\\ &= \begin{cases} 1 & \text{if } n = 0 \\ 2 * (S_{n - 1}) + 2 & \text{if } n > 0. \label{eq:recurrence2} \end{cases} \end{align} \]

This recurrence is the same as the original, except that it adds 1 to the answer. Now we let \(W_n = (S_n) + 1\) and \(W_{n - 1} = (S_{n - 1}) + 1\) and rewrite everything in terms of \(W\):

\[ \begin{align} W_n &= \begin{cases} 1 & \text{if } n = 0 \\ 2 * (W_{n - 1}) & \text{if } n > 0. \label{eq:recurrence3} \end{cases} \end{align} \]

Notice how the “\( + 2\)” in Equation \(\ref{eq:recurrence2}\) goes away, because the coefficient \(2\) in Equation \(\ref{eq:recurrence3}\) will multiply with the “\( + 1\)” from \(W_{n - 1}\) to get it back. Using this alternate recurrence, it’s easy to see that the solution is just \(W_n = 2^n\), because \(W\) can only grow by multiplying \(2\) to itself! Hence

\[ \begin{align} W_n = (S_n) + 1 = 2^n \end{align} \]

and subtracting 1 from all sides gives us

\[ \begin{align} (W_n) - 1 =S_n = 2^n - 1. \end{align} \]

The lesson here is that if it is difficult to find the solution to a recurrence, we can use basic algebra rules to transform the recurrence to something more amenable. In this case, all it took was adding 1 to the original recurrence.

I thoroughly enjoyed figuring this stuff out because possibly for the first time in my life I used my programming experience (recurrence/recursion, memoization) to help myself understand mathematics — not the other way around. The other way around was never enjoyable — calculating what `i`

was in some \(n\)th iteration of a `for`

-loop never really excited me.

I hope this explanation helps you better understand the first few pages of *Concrete Mathematics*; I had to read that part three times over to really “get it” (never having learned what induction is). And henceforth, I will never look at a string of consecutive 1’s in binary the same way again. 😃

In computer science, this process of avoiding the recalculation of previously known values is called

*memoization*and is useful in generating the first N values of a recursive algorithm in \(O(N)\) (linear) time.↩Note that if \(k_0 = 0\), then \([k_0, k_{m}]\) is the set of all natural numbers (zero plus the positive integers).↩

There is no need to prove the recurrence (Equation \(\ref{eq:recurrence}\)) as we have already proved it in the process of deriving it.↩

In

*Concrete Mathematics*2 ed. p. 3 (where the book uses \(T_n\) instead of \(S_n\)), the proof is simply a one-liner: \[ T_n = 2(T_{n - 1}) + 1 = 2(2^{n - 1} - 1) + 1 = 2^n - 1. \] But I find it a bit too terse for my tastes.↩

`2017-04-14`

*
math, programming, python

The Fibonacci Sequence is defined as follows:

\[ \begin{align} \mathrm{F}_{0} = 0\\ \mathrm{F}_{1} = 1\\ \mathrm{F}_{n} = \mathrm{F}_{n - 2} + \mathrm{F}_{n - 1}. \end{align} \]

That is, each Fibonacci number \(\mathrm{F}_{n}\) is the sum of the previous two Fibonacci numbers, except the very first two numbers which are defined to be 0 and 1. ^{1}

From the definition above, it appears that computing \(\mathrm{F}_{n}\) requires one to always compute \(\mathrm{F}_{n - 2}\) and \(\mathrm{F}_{n - 1}\). **This is false:** enter the “doubling method”. ^{2} ^{3}

The doubling method uses a couple of mathematical formulas derived from matrix multiplication as it applies to calculating Fibonacci numbers; it can be seen as an improvement over the matrix multiplication method, although it does not use matrix multplication itself. The matrix multiplication method uses the following formula:

\[ \begin{equation} \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix}^n = \begin{bmatrix} \mathrm{F}_{n + 1} & \mathrm{F}_{n}\\ \mathrm{F}_{n} & \mathrm{F}_{n - 1} \end{bmatrix}. \end{equation} \]

This result is quite interesting in its own right; to find \(\mathrm{F}_{n}\) you only need to raise the matrix

\[ \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix} \]

to the \(n\)th power. To be more precise, this method is matrix *exponentiation*. The only downside is that much of the answer is wasted — we don’t care about \(\mathrm{F}_{n - 1}\), not to mention how \(\mathrm{F}_{n}\) is redundantly computed twice.

What if we could find \(\mathrm{F}_{n}\) not by multiplying or adding some numbers, but by multiplying and adding *other Fibonacci terms*? Of course, we’re not talking about adding \(\mathrm{F}_{n - 2}\) and \(\mathrm{F}_{n - 1}\) because that would be too slow. Let’s have a look at the matrix identity again (reversed for easier reading):

\[ \begin{equation} \begin{bmatrix} \mathrm{F}_{n + 1} & \mathrm{F}_{n}\\ \mathrm{F}_{n} & \mathrm{F}_{n - 1} \end{bmatrix} = \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix}^n. \end{equation} \]

If we substitute in \(2n\) for \(n\), we get

\[ \begin{align} \begin{bmatrix} \mathrm{F}_{2n + 1} & \mathrm{F}_{2n}\\ \mathrm{F}_{2n} & \mathrm{F}_{2n - 1} \end{bmatrix} & = \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix}^{2n} \\ & = \bigg(\begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix}^{n}\bigg)^2 \end{align} \]

and we can substitute in our matrix identity from above to rewrite this as

\[ \begin{align} & = \bigg(\begin{bmatrix} \mathrm{F}_{n + 1} & \mathrm{F}_{n}\\ \mathrm{F}_{n} & \mathrm{F}_{n - 1} \end{bmatrix}\bigg)^2 \end{align} \]

and carry out the squaring to get

\[ \begin{align} & = \begin{bmatrix} {{\mathrm{F}_{n + 1}}^2 + {\mathrm{F}_{n}}^2} & {{\mathrm{F}_{n + 1}\mathrm{F}_{n}} + {\mathrm{F}_{n}\mathrm{F}_{n - 1}}}\\ {{\mathrm{F}_{n}\mathrm{F}_{n + 1}} + {\mathrm{F}_{n - 1}\mathrm{F}_{n}}} & {{\mathrm{F}_{n}}^2 + {\mathrm{F}_{n - 1}}^2} \end{bmatrix}. \end{align} \]

The top right and bottom left terms are identical; we can also rewrite them to be a bit simpler.

\[ \begin{align} {{\mathrm{F}_{n + 1}\mathrm{F}_{n}} + {\mathrm{F}_{n}\mathrm{F}_{n - 1}}} & = \mathrm{F}_{n}(\mathrm{F}_{n + 1} + \mathrm{F}_{n - 1}) \\ & = \mathrm{F}_{n}[\mathrm{F}_{n + 1} + (\mathrm{F}_{n + 1} - \mathrm{F}_{n})] \\ & = \mathrm{F}_{n}(2\mathrm{F}_{n + 1} - \mathrm{F}_{n}). \end{align} \]

This simplication achieves an important task — it obviates \(\mathrm{F}_{n - 1}\) by cleverly defining it as \(\mathrm{F}_{n + 1} - \mathrm{F}_{n}\). Putting everything together, whe have

\[ \begin{align} \begin{bmatrix} \mathrm{F}_{2n + 1} & \mathrm{F}_{2n}\\ \mathrm{F}_{2n} & \mathrm{F}_{2n - 1} \end{bmatrix} & = \begin{bmatrix} {{\mathrm{F}_{n + 1}}^2 + {\mathrm{F}_{n}}^2} & {\mathrm{F}_{n}(2\mathrm{F}_{n + 1} - \mathrm{F}_{n})}\\ {\mathrm{F}_{n}(2\mathrm{F}_{n + 1} - \mathrm{F}_{n})} & {{\mathrm{F}_{n}}^2 + {\mathrm{F}_{n - 1}}^2} \end{bmatrix} \end{align} \]

where the first row (or column) gives us two very useful identities

\[ \begin{align} \mathrm{F}_{2n} & = {\mathrm{F}_{n}(2\mathrm{F}_{n + 1} - \mathrm{F}_{n})} \\ \mathrm{F}_{2n + 1} & = {{\mathrm{F}_{n}}^2 + {\mathrm{F}_{n + 1}}^2}. \end{align} \]

As these identities form the heart of the doubling method, let’s call them the *doubling identities*.

And now we just need one more piece to formulate our doubling method; we need to borrow an idea from number theory. Given any positive integer \(n\), it is the same as either \(2m\) (even) or \(2m + 1\) (odd), where \(m = \lfloor\frac{n}{2}\rfloor\); for our purposes, let us call this property the “halving property”.

Whereas the doubling identities allow us to “double” our way into bigger numbers, the halving property allows us to halve our way down to smaller and smaller numbers. The marriage of these two concepts gives rise to the doubling method.

To compute the \(n\)th Fibonacci term we break \(n\) itself down into its halves (\(2m\)) recursively, until we go down to \(n = 0\). At this point we multiply our way back up using the doubling identities. Because halving and doubling by themselves always calculate \(\mathrm{F}_{2m}\), we have to manually return \(\mathrm{F}_{2m + 1}\) if our current sequence index number \(n\) is odd.

```
def fibonacci_doubling(n):
""" Calculate the Nth Fibonacci number using the doubling method. """
return _fibonacci_doubling(n)[0]
def _fibonacci_doubling(n):
""" Calculate Nth Fibonacci number using the doubling method. Return the
tuple (F(n), F(n+1))."""
if n == 0:
return (0, 1)
else:
a, b = _fibonacci_doubling(n >> 1)
c = a * ((b << 1) - a)
d = a * a + b * b
if n & 1:
return (d, c + d)
else:
return (c, d)
if __name__ == "__main__":
for n in range(20):
print(fibonacci_doubling(n))
# As a demonstration of this algorithm's speed, here is a large n.
print(fibonacci_doubling(10000))
```

Line 12 is where we do the halving. We use the right-shift operator to do this. Lines 13 and 14 are our doubling identities (I use the left-shift operator here because it feels more natural to me). The if-condition on line 15 returns \(\mathrm{F}_{2m + 1}\) if \(n\) was odd, and \(\mathrm{F}_{2m}\) otherwise.

For comparison, here is an iterative version. On the one hand it avoids Python’s recursion limit, but the downside is a small loss of elegance (we have to loop twice — first to build up the halving/doubling points, and again for the main loop).

I hope you enjoyed reading about this method of calculationg Fibonacci numbers as much as I enjoyed learning the math behind it. This algorithm can be sped up if it uses a faster multiplication algorithm as `a`

and `b`

get very large (e.g., Karatsuba multiplication). ^{4} Time complexity is \(\Theta(\log{n})\); it reminds me of the binary search algorithm, in how the problem space is halved repeatedly. Neat!

We can choose to define the first two terms as 1 and 1 instead, but this distinction is needlessly arbitrary.↩

There is actually a known formula for our purposes, where \[ \mathrm{F}_{n} = \frac{\varphi^n - (-\varphi)^{-n}}{2\varphi - 1}\] and \(\varphi = \frac{1 + \sqrt{5}}{2} \approx 1.6180339887\cdots\) (the golden ratio). Unfortunately this requires arbitrary-precision floating point calculations.↩

For more discussion, see https://www.nayuki.io/page/fast-fibonacci-algorithms.↩

Python already uses Karatsuba multiplication natively for large integers.↩

`2017-04-02`

*
programming, haskell

Yesterday I made a minimal working example of calling C from Haskell, where I call a simple C function to compute the greatest common denominator, or “GCD”. The Haskell portion only serves as a wrapper around the C function. This post is a brief look at the whole setup.

I used `ghc`

8.0.1, and `gcc`

5.4.0. ^{1}

```
2017-04-02-calling-c-from-haskell
├── build.sh
├── c
│ ├── gcd.c
│ └── gcd.h
└── hs
├── ffi.hs
└── GCD.hs
2 directories, 5 files
```

To compile the example, run the `build.sh`

script. Here is the expected output of the built executable:

```
$ ./hs/ffi
4
15
12
```

. The `gcd()`

C function is easy to work with because it is a pure function without side effects. You can run the `ffi`

binary against `valgrind`

to make sure that we are not leaking any memory (sample output below).

```
$ valgrind --error-exitcode=1 --leak-check=yes ./hs/ffi
==14582== Memcheck, a memory error detector
==14582== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==14582== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==14582== Command: ./hs/ffi
==14582==
==14582== Warning: set address range perms: large range [0x4200000000, 0x14200100000) (noaccess)
4
15
12
==14582==
==14582== HEAP SUMMARY:
==14582== in use at exit: 0 bytes in 0 blocks
==14582== total heap usage: 48 allocs, 48 frees, 60,006 bytes allocated
==14582==
==14582== All heap blocks were freed -- no leaks are possible
==14582==
==14582== For counts of detected and suppressed errors, rerun with: -v
==14582== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
```

Below are some things I tried, but could not get to work.

- I tried to delete the
`gcd.c`

file by moving the function definition in`gcd.c`

to`gcd.h`

(and delete`gcd.c`

entirely). I compiled the object file with`gcc -c -Wall -Wextra -Werror -o gcd.o gcd.h`

but then I got this error:

```
$ ghc --make ffi.hs ../c/gcd.o
[1 of 2] Compiling GCD ( GCD.hs, GCD.o )
[2 of 2] Compiling Main ( ffi.hs, ffi.o )
Linking ffi ...
../c/gcd.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
```

- In
`GCD.hs`

you can see the line`foreign import ccall "gcd.h gcd"`

. Instinctively I thought that the`gcd.h`

in`"gcd.h gcd"`

served as a kind of disambiguator, for where the`gcd()`

function came from. So then I defined another function named`gcd()`

in a different C header file (`gcd_other.h`

), compiled it separately, but got a “multple definition” error:

```
$ ghc --make ffi.hs ../c/gcd.o ../c/gcd_other.o
[1 of 2] Compiling GCD ( GCD.hs, GCD.o )
[2 of 2] Compiling Main ( ffi.hs, ffi.o )
Linking ffi ...
../c/gcd_other.o: In function `gcd':
gcd_other.c:(.text+0x0): multiple definition of `gcd'
../c/gcd.o:gcd.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
`cc' failed in phase `Linker'. (Exit code: 1)
```

The version of gcc should not matter at all – actually, any decent C compiler should work.↩

`2016-12-04`

*
programming

I just open-sourced my dotfiles! The repo is probably one of the older Git repos out there and has over 2000 commits! The first commit was made in March 10, 2009, over 7 years ago. Mind you, even by that time I had accumulated a whole suite of configs, and I even had an exotic setup with XMonad 0.8.1!

Here are some takeaways:

It’s nice to have clean commit history — every line of code can answer **why** it exists. You are doing yourself a disservice (in the long run) if you have overly terse commit messages. Generally speaking, be as verbose as you can be, but within reason. Keeping the first line of the commit message down to less than 80 characters goes a long way in setting the tone for any auxiliary paragraphs that follow.

I am quite proud of the richness of my commit messages. Pretty much everything makes sense and I don’t have to use Google to reason about my choices.

I’ve used a stupidly simple build system of creating symlinks to “install” my configuration — all with the help of a single `Makefile`

. It’s not very flexible, and to be honest my Shell sklls are much better than what they used to be such that I could replace this setup with a script. But alas, the need for such a change has not been serious enough to warrant it.

Moreover, having a simple “build” system ensures robustness; the more I get older, the more I value systems that have a long “bit-rot halflife”. I admire Knuth’s TEX system for this very same reason. And this is the same reason why I will probably not use anything higher-level than a shell script for the job.

Every long-living code repository ends up collecting clutter over the years. It’s important to delete such code (and of course any corresponding comments), to keep the codebase nimble. Ultimately, the less code you have to maintain, the better.

Software evolves. Always be on the lookout for better software, and new ways to configure them! Leverage the power of open source (free upgrades!) and make it work for you.

If not, you should definitely consider it — what have you got to lose? Keeping a configuration repo (distributed across home computers) is probably the best way for you to learn how to use a distributed source control system; indeed it was how I learned to use Git properly.

Happy hacking!

]]>`2016-12-03`

*
programming, emacs, vim

I’ve been using Vim (and now, Emacs with Evil mode) for years — and still, every once in a while I get a pleasant surprise. Today I learned that you can replay macros from Visual Line mode! So you don’t always have to record something like `j0`

at the end of your macro to get down to the next line. I.e., after recording your macro for just 1 line, select other lines that you want to replay the macro against with Visual Line mode (`V`

). To replay, do

```
:'<,'>g/^/norm @q
```

(assuming that you recorded your macro into the `q`

register with `qq...q`

).

Thanks to Chris McCord for the tip (seek to about 3:20 in the video).

]]>`2016-10-30`

*
programming, tex

For years, whenever I wanted to interact with the outer shell environment from Latex, I would use one of two methods:

- perform some shell step separately from Latex and inject it into the Latex sources, or
- save it somewhere else and pull it in from Latex with
`\input{foo}`

.

But I learned recently that it can be done much more simply, if you are willing to use Luatex!

Let’s assume that you keep your Latex document in source control and want to inject the Git hash into the document. First, define a new command called `\shell`

.

```
% Call shell! See http://tex.stackexchange.com/a/114939/30920.
\newcommand\shell[1]{\directlua{
local handle, err = io.popen([[#1]])
if not handle then
tex.print(err)
os.exit(1)
end
local result = handle:read("*a")
handle:close()
tex.print(result)
}}
```

Then use it like this:

```
\shell{TZ='America/Los_Angeles' date}
\shell{git describe --always}%
\shell{(( $(git --no-pager diff 2>/dev/null | wc -l) + $(git --no-pager diff --cached 2>/dev/null | wc -l) > 0 )) && echo '*'}
```

. I then use `lualatex --shell-escape foo.tex`

to compile it. This is actual code from a Luatex document of mine.

I am not sure which shell program gets invoked, but for most things it should not matter much.

Now you know how to shell out from Latex!

Happy hacking!

]]>