## Never Seek to Tell Thy Love

Posted on May 16, 2013.

I wrote a ballad for tenor voice and piano featuring lyrics from William Blake’s poem “Never Seek to Tell Thy Love.” From a music theoretic perspective, this is my most sophisticated composition to date. The piece is written in B major but borrows chords from G#, with a modulation to C major and finally to A minor. Unconventionally, the chord progression I -> III is featured prominently throughout, with III functioning primarily as a pre-dominant. The sheet music is free and you can get it here.

Bill Cutter, director of the MIT Concert Choir (of which I am an alumnus), offered to sing the piece to the accompaniment of Professor Charles Shadle, and together they gave an incredibly powerful performance:

Tags:  home music

## I Wrote Some "Classical" Music

Posted on May 13, 2013.

I’m taking a music theory/composition class at MIT called Writing in Tonal Forms. One of our class projects was to write a minuet and trio for string quartet in the tradition of 18th- and 19th-century Haydn, Mozart, and Beethoven. We had a professional string quartet from the Worcester Chamber Music Society perform our pieces! Here is the quartet reading my piece for the first time:

Thanks to Professor Shadle for guiding me in writing this piece and for recruiting the WCMS to perform it. Also thanks to Luyi Zhang for recording and uploading the video.

Tags:  home music

## Fluid and Responsive Grid Layouts

Posted on May 9, 2013.

Fluid and responsive layouts are becoming more commonplace in modern web designs. It’s important that web applications are usable on all kinds of devices, ranging from smartphones to high-resolution desktop displays. I often use the responsive grid system from Twitter Bootstrap to build these layouts, but there are a few problems with Bootstrap’s fluid grids:

1. The size of the gutters depends on how deeply nested the columns are. For example, suppose I have two main columns, and the gutter between them has width $$x$$. If one of those columns has two nested columns, then the internal gutter will be proportionally smaller than $$x$$. Visually, this looks incorrect.
2. Bootstrap’s responsive grid styles make it difficult to apply vertical margins to the rows. The problem is that in the markup, a row consists of several columns. But when the window width is below a threshold value (768px by default), the columns stack vertically—each column essentially becomes its own row. However, the markup doesn’t reflect this change, and neither do the styles. As a result, the vertical margins are not applied to every column. You can’t put vertical margins on the columns themselves either, because the margins will collapse on small screens (when columns have float: none), but not on larger screens (when columns have float: left).
3. On small displays, Bootstrap’s responsive margin on the body element forces you to add CSS fixes for any elements that should be full-width (such as a header bar or footer). This margin should be on container elements (see the next section), not body.

So I decided to write my own fluid and responsive grid system which doesn’t have these issues. The code is written in SASS, which compiles to CSS. If you just want the compiled CSS, you can get it here (or get the minified version here). Everything is open source and in the public domain.

### A Fluid Container

First, let’s build a container that resizes to fit the window, up to some maximum width. Later we can put our fluid grid layout in one of these.

/* --------------- */
/* Fluid container */
/* --------------- */

/* A container (and its padding) will not grow larger than this width. */
$container-max-width: 1210px; /* The horizontal padding around containers. */$container-gutter: 20px;

/* Main container class. */
.container {
width: 100%;
max-width: $container-max-width; padding-left:$container-gutter;
padding-right: $container-gutter; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; margin-left: auto; margin-right: auto; }  Using it couldn’t be easier: <div class="container"> Some content... </div>  Super exciting demo: Some content... Note that this is completely independent of the grid system. We can use containers without the grid system, and we don’t have to put the grid system in a container. ### A Responsive Grid Here’s the code for the grid layout itself. It has a number of tricks to make sure it works in all modern browsers (all the way down to IE7)—you certainly don’t need to understand it to use it. Notice that we can easily change how many columns there are, the gutter size, etc. /* ---------------------- */ /* Responsive Grid Layout */ /* ---------------------- */ /* The spacing between columns. */$column-gutter-width: 2%;

/* The number of columns in a row. */
$num-columns: 12; /* The width at which the responsive grid layout kicks in. */$stack-width: 768px;

/* All columns must be put in an element with the "row" class. */
.row {
*zoom: 1;
&:before, &:after {
display: table;
content: "";
}
&:after {
clear: both;
}
@media (max-width: ($stack-width - 1)) { &:after { clear: none; } } } /* Inside a ".row", add ".span-X" elements to fill the grid, where X is the number of columns to span. */ @for$i from 1 through $num-columns { .span#{$i} {
float: left;
*zoom: 1;
&:before, &:after {
display: table;
content: "";
}
&:after {
clear: both;
}
@media (max-width: ($stack-width - 1)) { margin-top: inherit; margin-bottom: inherit; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } float: none; &:after { clear: none; } } } } @for$i from 1 through $num-columns { .row > .span#{$i} {
width: (100% + $column-gutter-width) * ($i / $num-columns) -$column-gutter-width;
*width: (100% + $column-gutter-width) * ($i / $num-columns) -$column-gutter-width - 50% / ($stack-width / 1px); margin-left:$column-gutter-width;
*margin-left: $column-gutter-width - 50% / ($stack-width / 1px);
&:first-child {
margin-left: 0;
}
@media (max-width: ($stack-width - 1)) { width: 100%; *width: 100%; margin-left: 0; *margin-left: 0; } } } @for$i from 1 through $num-columns { .row > .offset#{$i} {
margin-left: $column-gutter-width + (100% +$column-gutter-width) * ($i /$num-columns);
*margin-left: $column-gutter-width + (100% +$column-gutter-width) * ($i /$num-columns) - 50% / ($stack-width / 1px); &:first-child { margin-left: (100% +$column-gutter-width) * ($i /$num-columns);
*margin-left: (100% + $column-gutter-width) * ($i / $num-columns) - 50% / ($stack-width / 1px);
}
@media (max-width: ($stack-width - 1)) { margin-left: 0; *margin-left: 0; &:first-child { margin-left: 0; *margin-left: 0; } } } } @for$i from 1 through $num-columns { @for$j from 1 through ($i - 1) { .span#{$i} > .span#{$j} {$scale_factor: 100% / ((100% + $column-gutter-width) * ($i / $num-columns) -$column-gutter-width);
width: ((100% + $column-gutter-width) * ($j / $num-columns) -$column-gutter-width) * $scale_factor; *width: ((100% +$column-gutter-width) * ($j /$num-columns) - $column-gutter-width) *$scale_factor - 50% / (($stack-width / 1px) *$num-columns / $i); margin-left:$column-gutter-width * $scale_factor; *margin-left:$column-gutter-width * $scale_factor - 50% / (($stack-width / 1px) * $num-columns /$i);
&:first-child {
margin-left: 0;
}
@media (max-width: ($stack-width - 1)) { width: 100%; *width: 100%; margin-left: 0; *margin-left: 0; } } } } @for$i from 1 through $num-columns { @for$j from 1 through ($i - 1) { .span#{$i} > .offset#{$j} {$scale_factor: 100% / ((100% + $column-gutter-width) * ($i / $num-columns) -$column-gutter-width);
margin-left: ($column-gutter-width + (100% +$column-gutter-width) * ($j /$num-columns)) * $scale_factor; *margin-left: ($column-gutter-width + (100% + $column-gutter-width) * ($j / $num-columns)) *$scale_factor - 50% / (($stack-width / 1px) *$num-columns / $i); &:first-child { margin-left: (100% +$column-gutter-width) * ($j /$num-columns) * $scale_factor; *margin-left: (100% +$column-gutter-width) * ($j /$num-columns) * $scale_factor - 50% / (($stack-width / 1px) * $num-columns /$i);
}
@media (max-width: ($stack-width - 1)) { margin-left: 0; *margin-left: 0; &:first-child { margin-left: 0; *margin-left: 0; } } } } }  Again, using it is very simple. The markup is compatible with Bootstrap’s grid system. Here is a simple two-column layout: <div class="row"> <div class="span6"> Left column! </div> <div class="span6"> Right column! </div> </div>  And this is what it looks like: Left column! Right column! Of course, you can nest columns: <div class="row"> <div class="span6"> <div class="span3"> Left column A! </div> <div class="span3"> Left column B! </div> </div> <div class="span6"> <div class="span3"> Right column A! </div> <div class="span3"> Right column B! </div> </div> </div>  And this is what you get: Left column A! Left column B! Right column A! Right column B! You can also skip columns with offset classes: <div class="row"> <div class="span5"> Check out that space on my right! </div> <div class="span5 offset2"> Check out that space on my left! </div> </div>  Another super exciting demo: Check out that space on my right! Check out that space on my left! These layouts will expand to fill whatever element you put them in (that’s the “fluid” part), such as the container class we defined above. When the screen width is small, the columns will stack (that’s the “responsive” part). ### Responsive Styles For devices with small screens, we often don’t want all of the columns to stack. We may want to hide some information on mobile devices to save screen space. Here are some useful classes, inspired by their Bootstrap analogues, that can be used to conditionally display elements based on the screen size: /* ----------------- */ /* Responsive Styles */ /* ----------------- */$min-width-tablet: 768px;
$min-width-desktop: 980px; /* Phones */ @media (max-width: ($min-width-tablet - 1)) {
.phone-hidden, .tablet-visible, .desktop-visible {
display: none;
}
}

/* Tablets */
@media (min-width: $min-width-tablet) and (max-width: ($min-width-desktop - 1)) {
.phone-visible, .tablet-hidden, .desktop-visible {
display: none;
}
}

/* Desktops */
L2:
cmpl $999999999, -20(%rbp) setle %al testb %al, %al jne L3  Let’s go through this line by line. The first line tells the processor to jump to the L2 label, which is the conditional part of the loop. The second line is a label representing the beginning of the loop body. The third line corresponds to ++i in the source. Line 4 is the label we jumped to from Line 1, marking the start of the conditional part of the loop. Computing whether i < 1000000000 is a multi-step process: First, Line 5 computes i - 999999999 and updates the EFLAGS register with the result. The setle instruction on line 6 then looks at this register to determine whether i <= 999999999, storing the result in the AL (accumulator) register. The testb instruction on line 7 does a bitwise AND of AL with itself, updates ZF (the zero flag), and discards the result (i.e. this instruction tests if AL is zero). Finally, line 8 tells the processor to jump back to the beginning of the loop if ZF is unset. This is not an efficient way to count to a billion! Interestingly, the math reveals that we are doing 2.8 billion instructions per second on my 2.6 GHz CPU. On CISC processors like my Intel Core i7, it is common to execute on average more than one instruction per clock cycle. This is due to instruction-level parallelism. ### C++ (Optimized) Here is the assembly listing for the same code compiled with optimization level 1 (-O1):  movl$1000000000, %edx
L2:
subl \$1, %edx
jne L2


If we tell g++ to optimize the code any further, the optimizer actually removes the loop entirely! Notice that this assembly counts down from a billion rather than up. Compilers do weird things with your code. This version ran in 0.284 seconds. That’s more than 6 times faster than the version above.

The assembly is pretty straightforward. Line 1 moves the value 1000000000 into the EDX register. Line 2 is a label that marks the start of the loop body. Line 3 decrements the EDX register. Line 4 tells the CPU to jump to the beginning of the loop if EDX is nonzero.

The core loop consists of two instructions (the decrement and the jump). 2 billion instructions in 0.284 seconds is 7 billion instructions per second! Again, instruction-level parallelism is responsible for this incredible performance on a single core.

### Python

Now let’s write the same code in Python.

i = 0
while i < 1000000000:
i += 1


This is a direct line-by-line translation from the C++, and took 58.01 seconds in CPython, the most popular Python implementation. That’s about 33 times slower than unoptimized C++, and 204 times slower than optimized C++. Here are the opcodes, again, just for fun:

0 LOAD_CONST                1 (0)
3 STORE_FAST                0 (i)
6 SETUP_LOOP               26 (to 35)
15 COMPARE_OP               0 (<)
18 POP_JUMP_IF_FALSE       34
28 STORE_FAST               0 (i)
31 JUMP_ABSOLUTE            9
34 POP_BLOCK


Lines 4-12 are the opcodes that are run each iteration of the loop. So 1 billion * 9 opcodes / 58.01 seconds = about 155 million opcodes per second. It’s like we’re in the 1990s!

So, Python is slow. What else is new? Let’s compare Python to another dynamic programming language.

### JavaScript

JavaScript and Python runtimes have a similar job—to execute source code in their respective languages. Both languages are dynamically-typed, which is a crutch to static optimization. We would expect their performance to be comparable. Here’s the JavaScript version of the benchmark:

var i = 0;
while (i < 1000000000)
++i;


I’m testing this in V8, which is the fastest JavaScript runtime at the time of this writing. JavaScript takes 2.32 seconds. That’s comparable to the unoptimized C++ version! The neat thing about V8 is that if you write JavaScript like C++, it will perform like C++. Most web applications, however, use frameworks that take advantage of JavaScript’s dynamic nature (prototypical inheritance, reflection, dynamic types, etc.) and run much slower.

### Conclusion

So, while Python is invaluable as a tool for prototyping or writing IO-bound applications, its CPU-bound performance is behind the times. Other dynamic programming languages are rapidly approaching the performance of native code, whereas Python is still slowly chugging along behind.

Tags:  home