<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/pretty-feed-v3.xsl" type="text/xsl"?>
<rss version="2.0" 
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>ciju&apos;s curiosities and explorations</title>
    <description>Personal website and writings of ciju, exploring programming, mental models, learning, and technology and more</description>
    <link>https://ciju.in</link>
    <atom:link href="https://ciju.in/rss.xml" rel="self" type="application/rss+xml"/>
    <language>en-us</language>
    <copyright>© 2026 ciju</copyright>
    <managingEditor>ciju@ciju.in (ciju)</managingEditor>
    <webMaster>ciju@ciju.in (ciju)</webMaster>
    <lastBuildDate>Sat, 24 Jan 2026 07:15:28 GMT</lastBuildDate>
    <generator>Custom RSS Generator v2.0</generator>
    <ttl>60</ttl>
    <image>
      <url>https://ciju.in/profile-light.jpeg</url>
      <title>ciju&apos;s curiosities and explorations</title>
      <link>https://ciju.in</link>
    </image>
    <category>Technology</category>
    <category>Programming</category>
    <category>Data Visualization</category>
    <category>Mental Models</category>
    <item>
      <title>Understanding Time Zone</title>
      <description>Building a mental model around Time Zone</description>
      <link>https://ciju.in/writings/understanding-timezones</link>
      <guid isPermaLink="true">https://ciju.in/writings/understanding-timezones</guid>
      <pubDate>Sat, 17 Feb 2024 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<h2>Introduction</h2>
<p>Time Zone seems like a simple enough concept. Get offset for a place and
add/subtract it from UTC. If you are lucky, you will live your life without
knowing more. If you are unlucky, you will face issues in production, and not
for lack of trying, internet full of trivia, or list of falsehoods that
programmers believe about it, few good articles on how to approach it, but very
few resources on how to think clearly about itIf you have
tried to understand Time Zone, you likely found a few
<a href="https://www.zainrizvi.io/blog/falsehoods-programmers-believe-about-time-zones/">resources</a>
with
<a href="https://www.creativedeletion.com/2015/01/28/falsehoods-programmers-date-time-zones.html">list</a>
of
<a href="https://medium.com/@gonzaloohk/understanding-time-zones-part-1-3469a6327905">fallacies</a>
and what's <a href="https://www.youtube.com/watch?v=-5wpm-gesOY">wrong with Time Zone</a>.
If you persist, you will come across suggestions like <em>use UTC for timestamp</em>,
and in the best case, articles on how it's
<a href="https://swizec.com/blog/saving-time-in-utc-doesnt-work-and-offsets-arent-enough/">more</a>
<a href="https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/">complicated</a>
and some <a href="https://w3c.github.io/timezone">useful guidelines</a>.</p>
<p>Time Zone is a result of time, history, geography, politics, technology,
population, convenience and more. And although that is a lot of context, the
solution itself is not that complicated. This article aims to share a mental
model behind Time Zone. It might be incomplete, or wrong, but it should be a
good enough starting place, unless you prefer rules, trivia and list of
falsehoods as better source of learning.</p>
<p>In this article, we will create a mental modelI think of
mental models as the base on which to build your understanding. Details matter.
But without mental models, I find the details to be more individual facts than
connected information. See <a href="http://ciju.in/writings/understanding-financial-functions-excel-sheets">Understanding financial functions in Excel/Google
Sheets</a>
as another example of how mental models help. of Time Zone. Learn how
advice like <em>Always save timestamps as
<a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a></em> may not
work for your situation. Look at how to apply the mental model in your
application design. We will look at falsehoods, only to learn to ignore them.</p>
<p>To approach this topic, first, we will summarize the historical context of the
Time Zone. Next, we will build the mental model. And finally, we will look at
applying this model. So let's start with historical context.</p>
<h2>Why Time Zone?</h2>
<p>The history of Time Zone begins with the history of tracking <strong>time</strong>. In turn,
tracking time is influenced by celestial motion, history, geopolitics and
more<a href="https://www.quantamagazine.org/what-is-time-a-history-of-physics-biology-clocks-and-culture-20200504/">Time</a>
is a fascinating topic in itself. The <a href="https://ciju.in/writings/a-play-with-universe">scale of
it</a>, physics involved, infra
around it, history, culture and much more. Hopefully, another write-up in the
future.. If you are aware that Time Zone works with UTCWhich follows Gregorian Calendar and 24 hours, 60 minutes, 60 seconds
clock. And the occasional pesky leap/skip second., that it defines
offset for regions identified by Time Zone ID, and that many Time Zones have
rules to adjust their offsets for seasons, all of which can change based on
geopolitics and are managed as a dataset at
<a href="https://github.com/eggert/tz/">eggert/tz</a> etc, then you can skip to: <a href="#how-we-use-time-zone">How we
use Time Zone?</a>. Otherwise, this section will help you
with brief historical context. Few themes that reappear in this section:</p>
<ul>
<li>
<p><strong>Time and related concepts were invented in response to our needs for coordination. And evolved into their current form as our needs for coordination evolved.</strong></p>
</li>
<li>
<p><strong>Much of how we track time is a result of historical happenstance.</strong></p>
</li>
<li>
<p><strong>The universe doesn't care about our convenience, but still we got lucky.</strong></p>
</li>
</ul>
<p>Be advised, this section is <em>full of rabbit holes of topics to dive into</em> :)
There are expandable sections called <em>Curiosity</em>; raising questions to help
you appreciate the context behind the current choices. </p>
<p>We start with celestial mechanics visible to us.</p>
<h3>Sun, Moon, Stars and us</h3>
<p>The rhythms of life on Earth are roughly synchronized with</p>
<ol>
<li>Its spin — giving us day and night</li>
<li>Its rotation around the Sun — giving us seasons</li>
<li>Moon's rotation around it — giving us <a href="https://moon.nasa.gov/moon-in-motion/earth-and-tides/tides/">tides</a></li>
</ol>
<p>Our biology has <a href="https://en.wikipedia.org/wiki/Circadian_rhythm">adapted</a> to
these cycles. Like being awake/active and asleep/recovering, seasons, crop
cycles.</p>
<p>These celestial mechanisms lead to an important part of how we track time: <strong>Calendars</strong>.</p>
<h3>Calendars</h3>
<p>The Earth's spin is what we experience as a day. The number of times the earth
spins while rotating around the Sun is around
<a href="https://en.wikipedia.org/wiki/Tropical_year">365.2421</a>. The number of days that
the Moon does a complete cycle around the Earth is 29.53And these
numbers depend on how you count. See: <a href="https://www.youtube.com/watch?v=IJhgZBn-LHg">The Earth Moves -
Vsauce</a>, <a href="https://en.wikipedia.org/wiki/Year">Year -
Wikipedia</a>.. Notice how these are
not whole numbers, and Earth's cycle (365.2421) is also not a whole multiple of
the Moon's cycle (29.53). These cycles are slightly out of sync with each other.
And these are not stable. Earth's spin is slowing, slowly<a href="https://www.discovermagazine.com/planet-earth/the-earths-rotation-is-gradually-slowing-down">Hundreds of
millions of years ago, a day was only about 22 hours
long</a>.
The moon is, slowly moving away from Earth. Surprisingly, Earth's motion around
the Sun seems to be relatively stable<a href="https://en.wikipedia.org/wiki/Future_of_Earth">Future of
Earth</a>. Still, these
rhythms are roughly in sync, for us to consider them as subdivisions. Days
grouped into months, and months grouped into years. We came up with calendars to
track these.</p>
<p>Calendars were used as early as 6000BC. Of course,
<a href="https://en.wikipedia.org/wiki/History_of_calendars">history</a> is a lot more
complicated. Different calendars with different days, months, yearsThere are many other
<a href="https://en.wikipedia.org/wiki/List_of_calendars">calendars</a>, some of them still
in use. <a href="https://www.webexhibits.org/calendars/year.html">Calendars through the
Ages</a> is an interesting
read.. As humanity got more connected (first Julian and later) the
Gregorian calendarCalendars are trying to codify celestial mechanics
into simple rhythms. Even the Gregorian calendar is an approximation for this, and
should work for another <a href="https://www.nationalgeographic.com/science/article/160226-leap-year-science-time-world-cultures-february">few thousand
years</a>.
became the norm — a historical happenstance.</p>
<ul>
<li>What if we lived on a moon circling a planet, which was circling a star?</li>
<li>What if our planet didn't have a moon?<a href="https://www.youtube.com/watch?v=iJ_7aDGKw0E">How did we get a
moon?</a> and <a href="https://www.lpi.usra.edu/education/explore/marvelMoon/background/moon-influence/">How does it influence
us?</a></li>
<li>What if we evolved on <a href="https://www.space.com/42598-tatooine-like-alien-worlds-habitable-exomoons.html">a moon of an exoplanet, in a multi-start
system</a>?</li>
<li>What if Earths orbit was more elliptical?</li>
<li>What if another calendar was chosen, instead of Gregorian calendar?</li>
<li>What if we started colonizing moon or Mars?</li>
<li>Did people care about birthdays before calendars?</li>
</ul>
<p>Calendars helped us sync activities across days, months, and years. What about
within a day? That's where clocks come in.</p>
<h3>Clocks</h3>
<p>Clocks also have a long
<a href="https://en.wikipedia.org/wiki/History_of_timekeeping_devices">history</a>. Many
civilizations developed clocks like water, sand, candle clock, sundials. And
used them to divide the day into smaller parts. By the 14th century, monasteries
were using <a href="https://en.wikipedia.org/wiki/Turret_clock">Turret Clocks</a> for
syncing activities like prayersIn medieval Europe, purely
mechanical clocks were developed after the invention of the bell-striking alarm,
used to signal the correct time to ring monastic bells. <a href="https://en.wikipedia.org/wiki/History_of_timekeeping_devices">History of
timekeeping devices -
Wikipedia</a>
. Towns started to have clocks in town squares to coordinate
activities within them. These clocks were mostly tracking the local position of
the Sun. E.g. it wouldn't matter if two towns 200km apart had time
differing by &#x3C;OverNote inlineContent="7 min" overContent={Earth's
circumference is . A day has . Assuming the two cities are on meridian, mean solar time
difference: .} />. Towns had their own local tracking of time. Meanwhile, clocks
were getting more precise and portable, driven by the use case of accurate time
for sea <a href="https://en.wikipedia.org/wiki/Marine_chronometer">navigation</a>.</p>
<p>Somewhere along this journey, 24-hour clocks became prevalent. Note that, like the
Gregorian calendar, the 24-hour clock was something we converged on. A historical
happenstanceTo read more about the history, try <a href="https://www.goodreads.com/book/show/1837048.Time_s_Pendulum">Time's Pendulum - Jo
Ellen Barnett</a> or
<a href="https://en.wikipedia.org/wiki/History_of_timekeeping_devices">History of timekeeping devices -
Wikipedia</a>, <a href="https://en.wikipedia.org/wiki/24-hour_clock">24-hour clock - Wikipedia</a> and
<a href="https://hsm.stackexchange.com/questions/3512/have-there-been-accurate-alternative-clocks-ways-to-tell-time">more</a>..</p>
<ul>
<li>What if Earths orbit time around sun was shorter than it's spin (our day)?</li>
<li>What if a different clock<a href="https://en.wikipedia.org/wiki/Italian_six-hour_clock">6-hour
clock</a>, <a href="https://en.wikipedia.org/wiki/Decimal_time">Decimal
time</a>, <a href="https://en.wikipedia.org/wiki/Swatch_Internet_Time">Swatch Internet
Time</a>,
<a href="https://en.wikipedia.org/wiki/Muhurta">मुहूर्त</a> and more was chosen?</li>
<li>What if <a href="https://www.cambridgemaths.org/blogs/time-to-have-your-mind-blown/">midnight was 6 instead of
12</a></li>
</ul>
<p>As clocks improved, we started synchronizing our daily lives based on clock time
(Sun became secondary). Meanwhile, the world was getting more connected. Which
meant a need for syncing/coordinating across different regions.</p>
<h3>Time Zones</h3>
<p>It began around the 1850s, when trains started to appear as a mode of public
transport. Soon, people could travel between cities. Now people travelling
across the city would have to <a href="https://www.trains.com/trn/railroads/history/how-railroads-standardized-time-in-the-us/#:~:text=A%20passenger%20on,Vincennes%2C%20Ind.%2C%20time.">sync their
clocks</a>
with the city clock. A 7 min difference in clocks between two
stations 200km apart, would have lead to
confusionSomewhat similar to what we might face with
<a href="https://www.reddit.com/r/NoStupidQuestions/comments/oqzprv/do_flight_tickets_take_into_account_time_zone/">flights</a>
<a href="https://www.skytough.com/post/what-timezone-do-you-use-when-flying">today</a>..
Especially with trains needing to synchronize their movements. So, we (mostly
countries with railways) came up with a system to have the same time for most
cities within a country/region. This was essentially a scaled up version of a
town's local time. Time for the whole region was based on the Sun's rhythm at a
place in the region Railway made it possible to travel
fast enough over long distances to require continuous re-setting of timepieces
as a train progressed in its daily run through several towns. Starting in 1847,
Britain established Greenwich Mean Time, the mean solar time on the Prime
Meridian at Greenwich, England, to solve this problem: all clocks in Britain
were set to this time regardless of local solar noon.  <a href="https://en.wikipedia.org/wiki/Universal_Time">Universal
Time - Wikipedia</a>
.</p>
<p>Soon, international travel and communication became frequent enough to
standardize on how the clock times across countries are related to one another.
With the context of the Gregorian Calendar and 24-hour days, as the world got
more connected, Time Zones were invented. We came up with Time Zones to
standardize offsets used by countries. Two things were needed for this. One, a
timeline that all countries agreed on. This is (initially GMT and later) UTC.
And second, offsets from UTC (which we will get to shortly).</p>
<h4>UTC</h4>
<p>To sync time between different clocks, we required a reference timeline. GMT was
this timeline. GMT was based on <a href="https://www.rmg.co.uk/stories/topics/greenwich-mean-time-gmt">mean of solar
time</a>, as measured
from Greenwich. Around the 1970s, we started using atomic clocks, which were
good enough to keep time better than solar measurements. UTC (Coordinated
Universal Time) is derived from a statistical aggregate of some <a href="https://en.wikipedia.org/wiki/International_Atomic_Time">450 atomic
clocks</a>. UTC became the
base of most of our time infrastructure. UTC labels the timeline in terms of the
Gregorian calendar and 24-hour clock.</p>
<h4>Offsets</h4>
<p>With a reference timeline, countries would declare offset for their regions.
Here the standardization helped with making the offsets more
practicalBy about 1900, almost all inhabited places on Earth had
adopted a standard time zone, but only some of them used an hourly offset from
GMT. Many applied the time at a local astronomical observatory to an entire
country, without any reference to GMT. It took many decades before all time
zones were based on some standard offset from GMT or  <a href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">Coordinated Universal
Time</a> (UTC).
 <a href="https://en.wikipedia.org/wiki/Time_zone">Time zone</a>.
India's offset around 1940 was 5:21:10. Imagine trying to set up an online meeting
with that offset in mind. With standardization, India's offset is now 5:30. For
synchronization across the world, 5:00 or 6:00 might have been more convenient, but
5:30 probably works better for most of the population in India for their synchronization with the Sun's apparent movement?</p>
<ul>
<li>What if we had decided on different clock, like <a href="https://en.wikipedia.org/wiki/Decimal_time">Decimal
time</a>?</li>
<li>What if England was not the most influential nation at the time, and there was
powerful civilization at Samoa or Hawaii?</li>
<li>What if GMT was chosen to be the time at Hawaii?</li>
<li>What if Time Zone offsets were only allowed to be positive numbers?</li>
<li>Are Time Zones used with other calendars?</li>
</ul>
<p>Standardized offsets helped with collaboration/syncing across regions.
Unfortunately, the story doesn't end here.</p>
<h4>DST</h4>
<p>Our planet goes around its star (the Sun), while spinning at a tilt of
23.4°<a href="https://climate.nasa.gov/news/2948/milankovitch-orbital-cycles-and-their-role-in-earths-climate/">The angle of tilt changes slightly, in a 100,000 year
cycle!</a>.
This tilt leads to differences in both duration and intensity of Sunlight,
through our year-long cycle around the SunThere are a
<a href="https://www.youtube.com/watch?v=-UlY-54ao08">few</a>
<a href="https://x.com/hdanchiano/status/1527171695596998657">nice</a>
<a href="https://observablehq.com/@dbridges/visualizing-seasonal-daylight">visualizations</a>
and <a href="https://www.youtube.com/watch?v=84aWtseb2-4">explanations</a> of
it.. As people started synchronizing their life with clocks (instead
of the Sun), we started noticing that the Sun was still out, while the clock said night. DST
was/is an attempt to help people synchronize with more sunlight in the
eveningMore recently, the concept of "Daylight Saving Time"
(DST) or "Summer Time" was adopted as a way of allowing people more sunlight
hours in the evening. DST varies from country to country (not to mention
locality-to-locality) and often has "special one-off" changes to accommodate
special events. Not all regions observe DST: usually those closer to the equator
do not need it. <a href="https://www.w3.org/TR/timezone/">Working with Time Zones -
W3C</a> .</p>
<p>Consider the year 2023 in Los Ángeles (<em>America/Los_Angeles</em>). On Sunday, 12 Mar 2023, 2:00am, clocks shifted forward by an hour. In other words, clocks went from 1:59am to 3:00am. There was no 2:30 that day. This also means evening timings are shifted 1 hour later, relative to the previous day. The sunset in Los Ángeles, <a href="https://www.timeanddate.com/sun/usa/los-angeles?month=3&#x26;year=2023">which was around 6pm on 11th March, happened at 7pm on 12th March</a>. And on Sunday, 5 Nov 2023, 02:00am, clocks shifted backward by an hour, from 1:59am to 1:00am. And the sunset, which happened around 6pm on the 4th, happening at around 5pm on the 5th. And, clocks read 1:30am twice, that day.</p>
<p>DST is the reason for most shifts in offsets. It impacts more people, than other
non-DST offset changes. Many of the developed countries implement DST. Which
means, every year, people in these countries experience offset shift, twice.</p>
<h4>Time Zone went south</h4>
<p>By now you should have a sense that <a href="https://blog.poormansmath.net/how-much-is-time-wrong-around-the-world/">Time Zone is a
compromise</a>
around nature's rhythm and us syncing our activities. DST is one part of that
compromise. There are some extreme examples of this compromise. North Pole and South Pole. For
some part of the year, the South Pole has 24 hours of daylight, and the North
Pole has 24 hours of darkness. Vice versa for the other parts of the year.
<em>Research stations near the South Pole (Antarctica) often use their country's
local time. And every so often, whatever is convenient</em>A fascinating <a href="https://mm.icann.org/pipermail/tz/2023-December/033317.html">Dec
2023 email thread around Time Zone of an Antarctica research
base</a> h/t <a href="https://nondeterministic.computer/@mjg59/111609926210404991">@Mathew
Garret</a>, and <a href="https://www.scientificamerican.com/blog/observations/time-has-no-meaning-at-the-north-pole/">another one about time one a research ship</a>.
.</p>
<ul>
<li>What if most our civilization development happened at the poles?</li>
<li>What if Earths <a href="https://en.wikipedia.org/wiki/Axial_tilt">Axial tilt</a> was 90°,
instead of 23.4°Another case of <em>we got lucky</em>.?</li>
</ul>
<h4>It's Geopolitical</h4>
<p>Now that we have covered the context for Time Zone (and DST), let's emphasize
the role of geopolitics in this. We standardized on reference time. And we
standardized the process of getting local time. That is, local time should be
defined as an offset to the standard reference time (UTC). But the offsets
themselves are decided by the governments. It's a geopolitical concern. If a
region splits into two geopolitical regions, it might create a new zone and a
new offset. If the people in power of a geopolitical region, decide on changing the region's offset, everybody outside would have to respect the rule to get local time for
that region. A DST rule could change. Countries might have <a href="https://devblogs.microsoft.com/oldnewthing/20030822-00/?p=42823">disputes</a> <a href="https://en.wikipedia.org/wiki/List_of_border_conflicts">over
borders</a>. <a href="https://www.jpost.com/middle-east/article-735621">Or
have internal disputes</a>. Some
people might have to deal with different Time Zones for different activities in their lives<a href="https://www.972mag.com/the-worlds-only-ethnic-time-zone/">The world’s only ethnic time zone
</a>, <a href="https://english.news.cn/20220328/8a1ad2ddbde14941a6f208f1f175b550/c.html">A tale of 2 time
zones in one piece of land
</a>
. Etc. In other words, <strong>we agree on the process of getting clock
time (get offset and add to UTC), but the offset itself can change with time</strong>.</p>
<p>For all these reasons, it makes sense to consider the Time Zone as an offset followed
by a <a href="https://data.iana.org/time-zones/tz-link.html#:~:text=Each%20main%20entry%20in%20the%20database%20represents%20a%20timezone%20for%20a%20set%20of%20civil%2Dtime%20clocks%20that%20have%20all%20agreed%20since%201970.">set of clocks (instead of a
region)</a>,
called <a href="https://en.wikipedia.org/wiki/Civil_time"><strong>civil time</strong></a>. Below is
a visualization of recorded offset and DST changes in the Time Zone. We still show Time Zones by region, since it's the common use-case. It only shows
changes since 1970, as the data is more reliable since then. Hover over a region
to see the number of changes. Click on the region to open up the relevant
part of the <a href="https://github.com/eggert/tz/">tzdb</a>, which has offset rules and
comments.</p>
<p>With this context, let's understand how Time Zones are used.</p>
<h2>How we use Time Zone</h2>
<p>We will only consider Time Zones from an application development perspective.
There are four broad use cases.</p>
<ol>
<li>Get civil time (official time followed by a region) from UTC (UTC → CT).</li>
<li>Vice versa (CT → UTC) for a particular <strong>region</strong></li>
<li>Convert between civil times (CT1 →
CT2).</li>
<li>Do arithmetic like UTC + Duration or CT +
Duration.</li>
</ol>
<p>Let's start with the straightforward case: <strong>UTC → CT</strong>.</p>
<h3>UTC → CT</h3>
<p>Previously, we saw that civil time is UTC plus an offset (thanks to
standardization efforts). So, if we can get an offset for a region, we can add
it to UTC to get the civil time. Here is a representation of this simple model.
We will build on it as we add more details.</p>
<p>The first problem we face is the geopolitical nature of <strong>regions</strong>. Time Zone
could have been defined for geographical boundaries. But as the definition of a
region can change (or, be contested), it makes sense that we have an
indirection: Time Zone ID. Time Zone ID usually refers to a region, but could be
used independent of it. Your browser reports <em><strong></strong></em> as your
Time Zone ID, likely set in your operating systemIf
configuration or users choice is not available, you can use
<a href="https://github.com/evansiroky/timezone-boundary-builder">maps</a> which chart out
the region boundaries, and use <a href="https://stackoverflow.com/a/16086964">geolocation with the
map</a> to get the Time Zone. Another less
reliable way is to use <a href="https://remysharp.com/2023/06/29/ip-to-timezone-the-hard-but-fast-way">IP address to guess Time
Zone</a> or
use services which do that or some
<a href="https://www.netlify.com/blog/how-to-get-timezone-in-javascript-with-edge-functions/">edge</a>
<a href="https://vercel.com/docs/edge-network/headers#x-vercel-ip-timezone">computes</a>..
The list of Time Zones along with their details is maintained at <a href="https://github.com/eggert/tz/">(tzdb)
eggert/tz</a> provided by
<a href="https://www.iana.org/time-zones">IANA</a>. The visualization we saw before is
built on this data. <a href="https://learn.microsoft.com/en-GB/troubleshoot/windows-client/system-management-components/daylight-saving-time-help-support">Another
one</a>
is being maintained by Microsoft, for its OS. We are going to assume IANA tzdb
for this articleSame mental models should apply to Microsoft
version also. Although, I don't understand why Microsoft keeps a separate <a href="https://learn.microsoft.com/en-GB/troubleshoot/windows-client/system-management-components/daylight-saving-time-help-support">data
set</a>
with it's own
<a href="https://techcommunity.microsoft.com/t5/daylight-saving-time-time-zone/egypt-2023-time-zone-update-now-available/ba-p/3794114#comments">maintenance</a>
<a href="https://techcommunity.microsoft.com/t5/daylight-saving-time-time-zone/mexico-2023-time-zone-updates-now-available/bc-p/3759640/highlight/true#comments">issues</a>.
You might be better off <a href="https://codeofmatt.com/what-is-a-time-zone/">using
NodaTime</a> or other alternatives.
And while we are at the topic of time zone data set, Rails has its own <a href="https://thoughtbot.com/blog/its-about-time-zones">subset
of Time Zones and naming
convention</a>. 🤷.</p>
<p>So, instead of region, we use Time Zone ID, which represents a region (or occasionally
a set of clocks in a region). Given the Time Zone and the UTC timestamp, we want to derive the
civil time. As mentioned before, Time Zones themselves are a geopolitical concern.
This means offsets can change with time. These changes are also maintained at
<a href="https://github.com/eggert/tz/">eggert/tz</a>. But it has a bigger implication. To
get the offset, we also need to pass in reference time (because the offset could have been
changed after or before that). So, our new model becomes: pass Time Zone and UTC,
to get the offset for a region (which uses tzdb) and then add the offset and UTC to
get the civil time.</p>
<p>What about DST? DST is like a planned offset change, that applies every year.
These are recorded as <strong>rules</strong> in tzdb. E.g., based on the rule, the time might
shift forward or backward (usually by an hour, but could be more or less). For
practical purposes, one can consider them to be offset changes. So, our mental
model doesn't change.</p>
<h3>CT → UTC</h3>
<p>This sounds simple enough, and it is until we consider the reverse. Converting
from civil time to UTC (CT → UTC). This conversion would
have been straightforward had the offsets remained unchanged. Unfortunately, as we saw earlier, the offsets change, and many regions
follow DST. These offset changes lead to a shift in local time. Either forwards
or backwards. Let's look at the implications visually.</p>
<p>UTC is always moving forwardexcept for leap seconds and it's affect on Unix timestamp, cover later in <a href="#unix-timestamp-and-leap-seconds">Unix timestamp and leap seconds</a>.
The timeline for civil time can have gaps and overlaps. This leads to three
possibilities when trying to convert local time to UTC.</p>
<ol>
<li>If there are no offset changes, civil time maps to UTC. This is the first
case in the visual.</li>
<li>A civil time could be invalid (no corresponding UTC time). This could happen
if civil time is user input. The second case in visual.</li>
<li>Civil time could map to two UTC timesWell, it's possible that a
country might decide to move back their civil time by 1 hour, but one hour
after the offset change, decides to move back 1 hour again, and one hour
after that, decides to move back 1 hours for the third time. What's the
maximum UTC timestamps that could map to same Civil time? Granted this would
be super confusing. And only done by a country trying to sabotage itself. But
still, it's a possibility.. This is the third case in the visual.</li>
</ol>
<p>In more formal language, the function (UTC → CT) is neither
<em>one-to-one</em>, nor <em>onto</em>. In other words, its inverse (CT → UTC)
is not a function. But, in practice, we can assume that the inverse
(CT → UTC) would lead to 0, 1 or 2 UTC timestamps. With 1 being
the most common case. This is important in how we deal with Time Zone arithmetic.</p>
<p>The cases of ambiguity and invalidity of CT → UTC is why people
suggest keeping time in UTC. We will add more nuance to the topic in the <a href="#application-design-concerns">next
section</a>.</p>
<h3>CT1 → CT2</h3>
<p>We looked at UTC → CT and CT → UTC. CT1 →
CT2 could be achieved by first doing CT1 → UTC and then UTC →
CT2. In other words, first convert from the source Time Zone to UTC, and then
from UTC to the target Time Zone.</p>
<h3>UTC, CT + Duration</h3>
<p>These are operations like adding a month to the time, or adding a day to the time, or
adding 300 hours to the timeSee <a href="https://nodatime.org/3.1.x/userguide/arithmetic">Noda Time documentation on Date
and time arithmetic</a> for
understanding different kinds of arithmetic. Arithmetic becomes more
complicated if we want to accommodate what is intuitive to usSome libraries like NodaTime differentiate between the intuitive
arithmetic versus where you add duration without adjusting for intuition. Most
libraries do the intuitive arithmetic. If you want explicit arithmetic, you can
get the number of days in month and add it explicitly.. When we say
same day next month, we usually mean same day from the start of next month, irrespective of whether the current
month has 28, 29, 30 or 31 days. Similarly, arithmetic around years should adjust for
leap years. Intuitive calendar arithmetic (day, week, month, and year) is common in
libraries. Complicated scenarios like the end of next month might be supported by helper functions in the library. Most date-time libraries would support these kinds of calendrical arithmetic.</p>
<p>But when it comes to timezone and time within a day, implementations vary widely.
UTC + Duration is somewhat straightforward. There is no offset. We don't need to worry about offset changes. Most libraries could handle UTC + Duration consistently. CT + Duration is <a href="https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/">more
complicated</a>.
We will only consider how Time Zone affects these calculations. E.g., the intent
of adding a day to a timestamp might be to get the same time the next day. But how
should one accommodate for a DST or an offset change within that period? There are a few ways in
which software libraries around Time Zone handle this. Remember the three cases?
Time Zone can stay the same (in the simplest case). And the other two are: Time Zone offset
can move forward, or backward. Let's consider concrete examples. You are in the
<em><strong>Europe/Copenhagen</strong></em> Time Zone. Let's say you want to add a day to 2019-03-30
3am. Unfortunately, the offset changed from +1 to
+2 on 2019-03-31 2am (civil time). Intuitively,
by <strong>a day</strong>, you probably meant the same time the next day. So adding a day to the time
above should result in 2019-03-31 3am. But if we blindly add
<strong>24 hours</strong> to 2019-03-30 3am, the result would be 2019-03-31
4amSome intuitive operations listed in the next version of browser date and time api (Temporal):
Adding or subtracting days should keep clock time consistent across DST transitions. For example, if you have an appointment on Saturday at 1:00PM and you ask to re-schedule it 1 day later, you would expect the reschedule appointment to still be at 1:00PM, even if there was a DST transition overnight.
Adding or subtracting the time portion of a duration should ignore DST transitions. For example, a friend you've asked to meet in 2 hours will be annoyed if you show up 1 hour or 3 hours later.
There should be a consistent and relatively-unsurprising order of operations.
If results are at or near a DST transition, ambiguities should be handled automatically (no crashing) and deterministically.<a href="https://tc39.es/proposal-temporal/docs/zoneddatetime.html#add">Temporal.ZonedDateTime.add</a>. Different Time Zone libraries handle these cases
differently. Here are the behaviours I have come across:</p>
<ol>
<li>
<p><em><strong>Doesn't support it: <a href="https://nodatime.org/3.1.x/userguide/arithmetic">Noda
Time</a></strong></em> - The library would
support other operations like <strong>UTC → CT</strong>, <strong>CT → UTC</strong>, and <strong>UTC +
Duration</strong>. You would have to do civil clock time arithmetic using those.</p>
</li>
<li>
<p><em><strong>Does arithmetic in UTC: <a href="https://hexdocs.pm/elixir/main/DateTime.html">Elixir
DateTime</a></strong></em> - Converts the
civil clock time to UTC, does arithmetic, and converts the result back to
civil time. This means it doesn't adjust for Time Zone shifts. This is the
case of 2019-03-31
4am in the example above. The time between start and
end will always be 24 hours. Note that because the resulting time is a
mapping from UTC → CT, it will never be invalid.</p>
</li>
<li>
<p><em><strong>Does what's intuitive: <a href="https://moment.github.io/luxon/">Luxon</a>,
<a href="https://github.com/tc39/proposal-temporal">Temporal</a></strong></em> - This is the case
where the arithmetic above would result in 2019-03-31
3am. When there are two possibilities, Luxon picks the source
timestamp offset. To do an explicit operation, you can add duration in hours.</p>
</li>
<li>
<p><em><strong>Does not support? <a href="https://day.js.org/">day.js</a></strong></em> - The implementation
does not adjust for Time Zone offset changes. In dayjs case, the library
<a href="https://github.com/iamkun/dayjs/issues/1805">doesn't support it</a>.</p>
</li>
</ol>
<p>So, if you are working with date time and Time Zone arithmetic, you have to
evaluate the library you are using. There are basically two cases the library
has to accommodate for. The case where the offset shifts forward. And the one where
it shifts back. I have listed three of these cases. Parse these cases with your
library and add a day, an hour, etc to understand what the library supports.</p>
<table>
<thead>
<tr>
<th>tz</th>
<th align="right">civil time</th>
<th align="right">UTC</th>
<th align="right">offset from</th>
<th align="right">offset to</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pacific/Apia</td>
<td align="right">2011-12-29 23:59:59.9999</td>
<td align="right"></td>
<td align="right">-10</td>
<td align="right">+14</td>
</tr>
<tr>
<td>Europe/Zurich</td>
<td align="right">2023-03-26 01:59:59.9999</td>
<td align="right"></td>
<td align="right">+2</td>
<td align="right">+3</td>
</tr>
<tr>
<td>Europe/Zurich</td>
<td align="right">2023-10-27 02:59:59.9999</td>
<td align="right"></td>
<td align="right">-3</td>
<td align="right">+2</td>
</tr>
</tbody>
</table>
<p>For Luxon, Temporal, and DayJS, here is an <a href="https://observablehq.com/d/ee74d9fcbd33d7a3">Observable playground</a>. <a href="https://dotnetfiddle.net/eQHH4o">Dotnetfiddle playground</a> for NodaTime.</p>
<h4>Date operations gotcha</h4>
<p>If all you care about is date (not time), you have to be careful with timezone arithmetic. Using date &#x26; time operations for date arithmetic might lead to some unexpected results, with Time Zone. E.g., if you
consider midnight as the start of the day, and you want to find day + 1, but offset changes
within that duration, depending on what your library chooses, you might get the
same day or next. If you don't care about the time component, and only want to
manipulate dates, you may prefer using date operations (if your library supports it) or
UTC. Except in rare cases, like the 24-hour shift in Samoa, UTC date
calculations should give you the right answer.</p>
<p>We have only covered offset changes in this section. Other kinds of changes, like a new region,
although rare, are still possible. If
Time Zone is critical for your application, I would suggest spending some time
<a href="https://codeofmatt.com/on-the-timing-of-time-zone-changes/">understanding</a> and
<a href="https://github.com/timparenti/tzdata-meta">keeping</a> <a href="https://mm.icann.org/pipermail/tz/">track</a> of
<a href="https://medium.com/servicios-a0/on-solving-the-tzdb-changes-problem-7b9fa8f96b86">changes</a>.</p>
<h2>Application design concerns</h2>
<p>With the mental model in mind, while designing applications, we could think of
time from two perspectives.</p>
<ol>
<li>Users intent.<a href="https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/">Jon
Skeet</a>
brings this up in his writings.</li>
<li>Whether the event is in the past or future.</li>
</ol>
<p>Let's consider the simpler case. <strong>Past events</strong>. This is where you record
the timestamp for when something happened in the past. For example, the time of birth,
or when a purchase was made. Recording them as UTC timestamps makes sense. But
also, depending on what the user is expecting, you might want to keep a record
of the time zone. For example, for a global app, to understand local daily rhythms, it would
have to differentiate events based on the region the event happened
in<a href="https://apple.stackexchange.com/questions/259486/how-does-apple-watch-activity-app-deal-with-timezone-changes">How does Apple Watch Activity app deal with timezone
changes?</a>.
For many applications, you can save users' time zone in their profile
configuration and convert UTC timestamps to civil time, while rendering the UI. But what if a user travels and uses your service? It's a decision you have to
make, based on your application and users' expectations.</p>
<p>Next, <strong>future events</strong>. Timestamps for future events are more complicated.
Because the offset could change. For future events,
it's important to understand if the user is expecting civil time. For example,
if you are a school, you have to respect their civil time. Schools might have
8 a.m. as their opening time. And it might keep it through DST changes (in other
words, restaurants open at 8 a.m. based on civil time). Again, you have to think
carefully about your applications and users' expectations. And if your user
expects local time, you might even have to save the time within the day, for the
time zone, and do arithmetic to get what the user is expecting.</p>
<h3>Few cases</h3>
<p>Let's look at a few cases to get some familiarity. We will assume DST of 1 hour, where applicable.</p>
<ul>
<li>
<p>Restaurant opening time: You run a real time food delivery app. Customers can
order from restaurant based on their operating time. Your region has DST. So,
every year, once time moves forward, and once, it moves back. Should your
restaurant operating time change based on DST? There is no straight forward
answer. It depends on restaurants. Likely, most restaurants would continue to
operate the same civil hours, in DST also. And software should implement what
restaurants implement in real world.</p>
</li>
<li>
<p>Calendar app: A user wants to create a recurring calendar event. Should the
event consider civil time or ignore offset changes (in which case the during
DST, event would be scheduled 1 hour earlier)? Intuitively, it makes sense to
follow civil time. But what if the event is shared with users in other Time
Zones? Let's consider another case, where user wants to create a one-off
future event. But before the event, government decides to change the offset
(or move a future DST earlier). Still, civil time might make sense. Unless the
event is shared with people in other Time Zones, in which case, it might make
sense to use the UTC time of the future event. From my understanding, Google
Calendar saves one-off events in UTC, and uses event timezone for recurring
events.</p>
</li>
<li>
<p>Counting streak: Let's say you want to track and show study streak (days of
study) for students. The students might want these to be counted based on
civil timeWhat happens with offset changes? Since we only care about
days, this could just be calendar calculations (no need for Time Zone
concerns), except for rare cases like Samoa moving forward by 24 hours in
dec 2011. Most date time libraries don't handle this case. Likely, the effort
of supporting this case, might not be worth the returns.. On the
other end, consider GitHub streak. GitHub streaks are recorded based on
calendar with UTC+0 offset.</p>
</li>
</ul>
<h3>Implementation concerns</h3>
<p>With the understanding of how Time Zone affects your application, here are some hints to implementation details:</p>
<ol>
<li>Storing time</li>
<li>Transferring time (serialization)</li>
<li>Time conversions</li>
<li>Updating tzdb</li>
</ol>
<p>I have only given pointers for these concerns. There are context specific
concerns to get into. Before discussing them, we first have to look at the
timeline that most systems use in practice: <a href="https://en.wikipedia.org/wiki/Unix_time">Unix
time</a>.</p>
<h4>Unix time and leap seconds</h4>
<p>Most computing systems don't use UTC directly. That's where Unix timestamp comes
in. Unix timestamp is <strong>number of seconds since <em>00:00:00 UTC on January 1,
1970</em> (the Unix epoch), skipping the leap seconds</strong>. Most systems keep track of
time as Unix timestamp (or some similar epoch representation). But they also
sync time with UTC (remember UTC is timeline that everyone agrees on.
Unfortunately, one can't figure out UTC locallyPhysics, Relativity,
reality etc.. We have built quite complicated infrastructure to
disperse UTC (this includes GPS Satellites). Since Unix time doesn't have the
concept of leap seconds, when those happen in UTC, the machine has to do
something with it. Common approach was to repeat/skipSkip if negative
leap second. There hasn't been a skip second as of the writing of this
article. a second, based on leap second. More recent (and better)
approach is to spread the leap second across the day. E.g. each second is just a
little longer/shorter.).</p>
<p>What does ignoring leap seconds give us? Ease of calculations. Number of seconds
in a day is always . But it
ignores leap seconds. If you really need precise calculations, like exact number of seconds between two timestamps. You would have to
find a way to include leap seconds. You could consider <a href="https://en.wikipedia.org/wiki/International_Atomic_Time">TAI</a>. If you have to record the leap seconds in
timestamps and keep track of them in time arithmetic, <a href="https://geometrian.com/programming/reference/timestds/">I wish you
luck</a>.</p>
<p>For storage, Unix time representation has different trade-offs compare to the
other common representation of time, ISO8601. Unix time is a representation of
UTC (which avoids wrong interpretation), but is not quite human friendly. On the
other hand, ISO8601 is human-readable but could be interpreted wrongly, and both
have slightly different sorting characteristicsFor example, ISO8601
allows for week representation, or skipping separators, adding offset etc. Which
lead to different sorting characteristics. If you are using ISO8601 in your
application, you also have to understand the context of whether it's UTC or
local time. Practically, these are not major concerns since most applications
use a subset of ISO8601 representation, and store time in UTC. <a href="https://www.reddit.com/r/ExperiencedDevs/comments/187qg93/comment/kbj28n2/">Timestamps: my
strong
opinion</a>
limited precision (events within a second could be sorted differently. Doesn't
support timezone. But creates confusion with offset representation.).</p>
<p>How does this affect time zone. Mostly, it doesn't. Instead of using offset with
UTC, offset is applied on Unix time. This leads to leap seconds being ignored in
Civil time also. Most libraries around time and Time Zone use Unix time or some
similar timeline. Which means, you as a application developer likely won't have
to deal with leap seconds. Now, let's get back to implementation concerns.</p>
<h4>Storing time</h4>
<p>Here mostly you have to understand what information is needed for <a href="https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/">users
intent</a>
(or whatever you decided based on that), and how to store that in your
persistence layer. Information might be UTC, for most cases. Time Zone (remember
to use IANA code) for few cases. And if you are dealing with future recurring
times, or future civil time, etc, you might have to consider saving that
information also. Or if your use case only deals with date, may be store just
the date (without time). As an example, consider a school management software.
School timings would usually follow local time and won't change with DST
(according to local clocks). What about one-off meetings by teacher/manager in
the school? Their repeating meetings would follow local clock (assembly happens
based on local clock). So, it would make sense to</p>
<h4>Transfer time</h4>
<p>You might have to serialize time to transfer or export it. It's best practice to
do so in standardized format like ISO8601. Unfortunately, the standard doesn't
include Time Zone ID. It supports offset, but by now you should know, offsets
can change for a time zone. Different libraries have adopted different
conventions. I would suggest following <a href="https://datatracker.ietf.org/doc/draft-ietf-sedate-datetime-extended/">Date and Time on the Internet:
Timestamps with additional information
</a> which
seems to be followed by
<a href="https://tc39.es/proposal-temporal/docs/#Temporal-ZonedDateTime">Temporal</a> and
suggested by <a href="https://w3c.github.io/timezone/#serializations">w3c</a>.</p>
<h4>Time conversions</h4>
<p>We have already seen that libraries have differences in how they handle certain Time Zone operations. I would suggest to first understand the operations your application might need, and then evaluate libraries for those use cases. I do think the approach used by Luxon and Temporal should work for most cases.</p>
<p>Also, be careful with using time (which includes date), when all you need is
date operations. If application only needs Date arithmetic, you could ignore Time
Zone (except for the rate cases where Time Zone changes could make a date
invalid (Samoa 2011), or repeat (hasn't happened yet)). If you want to support
Samoa, you have to get the time zone database and a library which supports
arithmetic over time zone.</p>
<h4>Updating tzdb</h4>
<p>Since the Time Zone database could be updated, for applications dealing with Time Zone, you would have to consider how to update the tzdb periodically. Browsers ship this with their regular updates. Many libraries support updating of the tzdb, e.g <a href="https://github.com/mathieuprog/tz#automatic-vs-manual-updates">Elixir tz</a>, <a href="https://nodatime.org/3.1.x/userguide/tzdb">Noda Time</a>.</p>
<p>That covers most of what I have figured out. But I can't end this post without
covering the often shared topic around Time Zone - fallacies.</p>
<h2>Shall we fallacy?</h2>
<p>Somehow it's fashionable to share fallacies around time and related topics. Perhaps we could have implemented better systems, but it shouldn't stop us from
building better understanding of current systems. I would rather, people share a
mental model which, even if wrong, might lead to more learning (and better
mental models) for readers. Dealing with Time Zone (and time) is not intuitive.
But complaining about it is not the solution. Anyhow, you can expand the section
below to understand how a mental model might be useful to look at, and promptly
ignore fallacies.</p>
<ul>
<li>A time zone is a numeric offset from UTC.</li>
<li>Timezone name and abbreviations are unique.</li>
<li>In the USA, If we know the state a person is in, we can determinate his
timezone.</li>
<li>An entire state follows the same rules for daylight saving time.</li>
<li>If you know what country a person is. You can determine their time zone.</li>
<li>There are only 24 time zones possible offer since they are in one-hour
increments.</li>
<li>When DST is in effect, all time zones advance their clocks by 1 hour.</li>
<li>There can only be two daylight saving time transitions in any given year.</li>
<li>UTC offsets go from -12 to +12</li>
<li>Every UTC offset corresponds to exactly one time zone</li>
<li>There are more countries in the world than time zones</li>
<li>Every time zone has exactly one agreed upon name</li>
<li>There is a standard format for declaring time zones</li>
<li>Daylight Saving Time starts at the same time every year</li>
<li>A country's time zone never changes</li>
<li>A country stays in the same time zone during Daylight Saving Time</li>
<li>Daylight Saving Time starts around March and ends around October</li>
<li>Every time zone has it’s own name</li>
<li>Every time zone has its own abbreviation</li>
<li>Your time zone library can recognize any time zone (you are using a library for this, right?)</li>
<li>The entire country always shifts during Daylight Saving Time</li>
<li>The entire state always shifts during Daylight Saving Time</li>
<li>Other than DST, every city within a state follows the same time zone</li>
<li>Every city sits within exactly one time zone</li>
<li>There’s a designated time zone for every location in the world</li>
</ul>
<ul>
<li>Time Zone will never change, so I only have to think about then when I first
build my application</li>
<li>A country stays at the same UTC offset all year long</li>
</ul>
<ul>
<li>There is always an unambiguous conversion from one time zone to another.</li>
<li>Time zones are always offset from UTC by an integer number of hours.</li>
<li>Fine, time zones are always offset from UTC by an integer number of half-hours. 😒</li>
</ul>
<p>A few <a href="https://madelinemiller.dev/blog/timezones-are-bad/">suggest</a> this in
<a href="https://www.reddit.com/r/programming/comments/jggx3l/comment/g9qycqw/">discussions</a>
<a href="https://remote.com/blog/whats-wrong-time-zones">around</a> Time Zone. Why is this
not practical? Consider how this would be implemented. All the institutions
(banks, government offices, schools, shops, restaurants) would have to change
their timings. Population of all nations would have to learn completely new way
of talking about their day time. All written references of civil time (a novel
charting a characters' day with day starting at 0), would read strange to
population which has a different hour for starting of day. I think Time Zone is
here to stay. We might make it less annoying, by abolishing DST.</p>
<h2>Parting suggestions</h2>
<p>Consider Time Zone as a database of mappings from Time Zone ID to offset, which
can change with time.  Use the
database to get the details and keep it updated. Avoid Time Zone
arithmetic. And if unavoidable, evaluate the existing libraries, instead of
implementing on your own.</p>
<p>Use fallacies to update your mental model. But otherwise, ignore them.</p>
<h2>Acknowledgment</h2>
<p>Thanks to <a href="https://saneef.com/">Saneef</a>, <a href="http://ananthakumaran.in/">Anantha
Kumaran</a>, <a href="https://dhruvasagar.dev/">Dhruva Sagar</a>
for reviewing the draft. And especially <a href="https://www.linkedin.com/in/arjun-karande-a022011/">Arjun
Karande</a> for giving much
needed critical feedback.</p>]]></content:encoded>
    </item>
    <item>
      <title>Understanding Financial Functions</title>
      <description>A visual understanding on how FV, PV, RATE, PMT NPER etc are related functions in Excel/Google Sheets.</description>
      <link>https://ciju.in/writings/understanding-financial-functions-excel-sheets</link>
      <guid isPermaLink="true">https://ciju.in/writings/understanding-financial-functions-excel-sheets</guid>
      <pubDate>Thu, 05 Oct 2023 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <media:content url="https://ciju.in/images/financial_fns/cashflows.png" medium="image" />
      <media:thumbnail url="https://ciju.in/images/financial_fns/cashflows.png" />
      <content:encoded><![CDATA[<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cgdef%5Cpv%7B%5Ctextcolor%7BBEA1A5%7D%7B%5Csmall%5Cit%7BPV%7D%7D%7D%0A%5Cgdef%5Cfv%7B%5Ctextcolor%7BBE4BDB%7D%7B%5Csmall%5Cit%7BFV%7D%7D%7D%0A%5Cgdef%5Cpmt%7B%5Ctextcolor%7B008FD3%7D%7B%5Csmall%5Cit%7BPMT%7D%7D%7D%0A%5Cgdef%5Crate%7B%5Ctextcolor%7B32B67A%7D%7B%5Csmall%5Cit%7BRATE%7D%7D%7D%0A%5Cgdef%5Cnper%7B%5Ctextcolor%7BFF4552%7D%7B%5Csmall%5Cit%7BNPER%7D%7D%7D" alt="\gdef\pv{\textcolor{BEA1A5}{\small\it{PV}}}
\gdef\fv{\textcolor{BE4BDB}{\small\it{FV}}}
\gdef\pmt{\textcolor{008FD3}{\small\it{PMT}}}
\gdef\rate{\textcolor{32B67A}{\small\it{RATE}}}
\gdef\nper{\textcolor{FF4552}{\small\it{NPER}}}" /></div>
<p>You might have used functions like FV, PV, XIRR in excel/google sheetsIn rest of the article, I will use excel to mean Excel, Google Sheets, OpenOffice etc. In my case, whenever I needed to model some financial calculations, I would struggle with search junk, find out some function, lookup the parameter order, try it out etc. More than that, I couldn't even think of functions like PMT, RATE etc. Turns out, understanding the underlying model makes it much easier to remember and use these functions. <img src="https://math.vercel.app/?from=%5Cpv%2C%20%5Crate%2C%20%5Cnper%2C%20%5Cpmt%2C%20%5Cfv" alt="\pv, \rate, \nper, \pmt, \fv" style="display: inline; vertical-align: middle;" /> are related. Given any four, the fifth value can be derivedIt's almost as if all these functions are different sides of the same coin, or more concretely, different ways of using the same equation.. Moreover, the underlying model could be quite useful in common man's financial jouney, be it loans or retirement. And it's not complicated. Here is a visual representation of the underlying model.</p>
<p>Rest of the article explains this visual and adds some more details.</p>
<h2>Cashflows - a visual representation</h2>
<p>These functions work on cashflows. What is cashflow? Basically money moving in and out of an asset or a liability. Assets (investments, etc) and liability (loans, etc) are handled the same way. It's just a matter of passing in different numbers (and their signs, +ve/-ve) to the functions.</p>
<p>To find the value, you would use  function in excel: PMT(0.10, 5, 3000, -100000)</p>
<p>Now, let's remove the specifics. First, it doesn't matter if the period 5 was years, months, quarters or something else. As long as the <strong>payments are done each period</strong>. And the <strong>interest rate is per period</strong>. So, we abstract away 5 years to <strong>5 periods</strong> and rename it  (presumably for N PERiods). Payment in each period is . Rename the money we expect in the end to  (Future Value). Rename 10% interest to . And the  initial money to  (Present Value). Here is the same excel calculation with new names: PMT(RATE, NPER, PV, FV).</p>
<h2>Functions on cashflow</h2>
<p>Now, looking at this general visual representation of cashflow, we could wonder, what if we want to know RATE, given NPER, PMT, PV, FV. Or some other combination. And it does work. Here is the list of these related functions available in most excel implementations.</p>
<p>Isn't it nice that even the parameters have a certain order? You can see the parameter order across functions, below. Pick the function you want to caculate, move it forward and rest is the order of the parameters to that function. In general, you start with some money (could be +ve, -ve or 0), put some money in (or take out), every period, for NPER periods. And in the end, you take out (or owe) some money. The parameters in [] are optional and if not give, default to 0.</p>
<pre><code class="language-fin-fun">[RATE, NPER, PMT, PV, FV]
</code></pre>
<p>And here is an interesting one use of this model NPER(interest, -savings_rate, 0, (1-savings_rate) ÷ withdrawal_rate), copied from <a href="https://bou.ke/blog/formulas/">Bouke's blog</a>. Given a interest rate for all future and your savings rate, it calculates the number of years till you have retirement moneyAssumes your withdrawl rate would be same after retirment. And rate is real interest rate. Is calculating with real interest correct? It seems so. Calculating with real interest instead of nominal, seems to be a pretty good approximation. See this <a href="https://docs.google.com/spreadsheets/d/1fyM7dbM6v9b5gqLZpNJf4M11hdRht0V3wwMlzIxnq7w/edit?usp=sharing">Google Sheet</a>..</p>
<p>If you are in India, here is another interesting one. Calculate the effective
annual rate of return for a ULIP that you have come across.
</p>
<p>Till now we dealt with cases where PMT (the money you pay/receive every period) and the period are same for the cashflows. In other words, you pay/receive the same amount every period. What if you have cashflows with different amount of payments. What if you have different cashflows and uneven periods (when you made the payments).</p>
<h3>Functions on changing cashflows</h3>
<p>First, let's consider the case where periods are same, with only the payments per period could be different from one period to another. The function IRR gives the rate of return. It's a single rate, which accounts for all the cashflows. NPV is the other function, to get the present value of the cashflows. There is no NFV, not sure why.  What about NPER, PMT? Given the payments, we implicitly have the payments and the periods!.</p>
<pre><code class="language-fin-fun">IRR(cashflow_amounts)
NPV(rate, cashflows_amounts)
</code></pre>
<p>What if both the payments and when you made them, can vary? E.g. ocassional investments made to a mutual fund. XIRR is a way to understand returns for these cashflows. And XNPV for present value. Again, no XNFV, although it seems to be less useful.</p>
<pre><code class="language-fin-fun">XIRR(cashflow_amounts, chasflow_dates)
XNPV(rate, cashflow_amounts, cashflow_dates)
</code></pre>
<p>These calculations for uneven periods and different payments, are iterative. Solving them involves guessing a value, and then iteratively improving on the guess. Unlike the ones for <img src="https://math.vercel.app/?from=%5Crate%2C%20%5Cnper%2C%20%5Cpmt%2C%20%5Cpv%2C%20%5Cfv" alt="\rate, \nper, \pmt, \pv, \fv" style="display: inline; vertical-align: middle;" />.</p>
<h2>Underlying calculation</h2>
<p>For constant period and payments, the underlying equation is relatively straighforward.</p>
<p>First consider the .</p>
<p>The first year, <img src="https://math.vercel.app/?from=%5Cpv" alt="\pv" style="display: inline; vertical-align: middle;" /> grows to</p>
<p><img src="https://math.vercel.app/?from=%5Cpv%20*%20(1%2B%5Crate)" alt="\pv * (1+\rate)" style="display: inline; vertical-align: middle;" /></p>
<p>Next year, it grows to</p>
<p><img src="https://math.vercel.app/?from=%5Cpv%20*%20(1%2B%20%5Crate)%20*%20(1%20%2B%20%5Crate)%20%5Cimplies%20%5Cpv%20*%20(1%2B%5Crate)%5E2" alt="\pv * (1+ \rate) * (1 + \rate) \implies \pv * (1+\rate)^2" style="display: inline; vertical-align: middle;" />.</p>
<p>After <img src="https://math.vercel.app/?from=%5Cnper" alt="\nper" style="display: inline; vertical-align: middle;" /> years, the PV grows to</p>
<p><img src="https://math.vercel.app/?from=%5Cpv%20*%20(1%2B%5Crate)%5E%7B%5Cnper%7D" alt="\pv * (1+\rate)^{\nper}" style="display: inline; vertical-align: middle;" /></p>
<p>This is the end value of <img src="https://math.vercel.app/?from=%5Cpv" alt="\pv" style="display: inline; vertical-align: middle;" />. Now let's consider <img src="https://math.vercel.app/?from=%5Cpmt" alt="\pmt" style="display: inline; vertical-align: middle;" />.</p>
<p>The first <img src="https://math.vercel.app/?from=%5Cpmt" alt="\pmt" style="display: inline; vertical-align: middle;" /> payment has <img src="https://math.vercel.app/?from=%5Cnper-1" alt="\nper-1" style="display: inline; vertical-align: middle;" /> years to grow. So, by the end of <img src="https://math.vercel.app/?from=%5Cnper" alt="\nper" style="display: inline; vertical-align: middle;" /> period, it would be</p>
<p><img src="https://math.vercel.app/?from=%5Cpmt%20*%20(1%2B%5Crate)%5E%7B(%5Cnper-1)%7D" alt="\pmt * (1+\rate)^{(\nper-1)}" style="display: inline; vertical-align: middle;" /></p>
<p>Second <img src="https://math.vercel.app/?from=%5Cpmt" alt="\pmt" style="display: inline; vertical-align: middle;" /> has <img src="https://math.vercel.app/?from=%5Cnper-2" alt="\nper-2" style="display: inline; vertical-align: middle;" /> years to grow. So, at the end of <img src="https://math.vercel.app/?from=%5Cnper" alt="\nper" style="display: inline; vertical-align: middle;" /> period, it will be
<img src="https://math.vercel.app/?from=%5Cpmt%20*%20(1%2B%5Crate)%5E%7B(%5Cnper-2)%7D" alt="\pmt * (1+\rate)^{(\nper-2)}" style="display: inline; vertical-align: middle;" /></p>
<p>And so on. If we add up value of all payments (<img src="https://math.vercel.app/?from=%5Cpmt" alt="\pmt" style="display: inline; vertical-align: middle;" />) at the end of <img src="https://math.vercel.app/?from=%5Cnper" alt="\nper" style="display: inline; vertical-align: middle;" />, it would be</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cpmt%20%5Ctimes%20(1%2B%5Crate)%5E%7B%5Cnper%20-%201%7D%20%2B%20%5Cpmt%20%5Ctimes%20(1%2B%5Crate)%5E%7B%5Cnper%20-%202%7D%20%2B%20%5Cldots%20%2B%20%5Cpmt%20%5Ctimes%20(1%2B%5Crate)%20%2B%20%5Cpmt" alt="\pmt \times (1+\rate)^{\nper - 1} + \pmt \times (1+\rate)^{\nper - 2} + \ldots + \pmt \times (1+\rate) + \pmt" /></div>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cimplies%5Cpmt%20%5Ctimes%20%5CBig(%20(1%2B%5Crate)%5E%7B%5Cnper%20-%201%7D%20%2B%20(1%2B%5Crate)%5E%7B%5Cnper%20-%202%7D%20%2B%20%5Cldots%20%2B%20(1%2B%5Crate)%20%2B%201%5CBig)" alt="\implies\pmt \times \Big( (1+\rate)^{\nper - 1} + (1+\rate)^{\nper - 2} + \ldots + (1+\rate) + 1\Big)" /></div>
<p>Squint at it a little and you will see the part in the big bracket being similar to.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=x%5E%7Bn-1%7D%20%2B%20x%5E%7Bn-2%7D%20%2B%20%5Cldots%20%2B%20x%20%2B%201" alt="x^{n-1} + x^{n-2} + \ldots + x + 1" /></div>
<p>Where <img src="https://math.vercel.app/?from=x%20%3D%20(1%20%2B%20%5Crate)" alt="x = (1 + \rate)" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=n%20%3D%20%5Cnper" alt="n = \nper" style="display: inline; vertical-align: middle;" />.</p>
<p>To simplify this equation, let's assume</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=S%20%3D%20x%5E%7Bn-1%7D%20%2B%20x%5E%7Bn-2%7D%20%2B%20%5Cldots%20%2B%20x%20%2B%201" alt="S = x^{n-1} + x^{n-2} + \ldots + x + 1" /></div>
<p>Multiply both sides by <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" />.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=xS%20%3D%20x%5E%7Bn%7D%20%2B%20x%5E%7Bn-1%7D%20%2B%20%5Cldots%20%2B%20x%5E2%20%2B%20x" alt="xS = x^{n} + x^{n-1} + \ldots + x^2 + x" /></div>
<p>Substracting the <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" /> from <img src="https://math.vercel.app/?from=xS" alt="xS" style="display: inline; vertical-align: middle;" />, we get.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=(x%20-%201)%5Ctimes%20S%20%3D%20x%5E%7Bn%7D%20-%201" alt="(x - 1)\times S = x^{n} - 1" /></div>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cimplies%0AS%20%3D%20%5Cfrac%7Bx%5E%7Bn%7D%20-%201%7D%7Bx-1%7D" alt="\implies
S = \frac{x^{n} - 1}{x-1}" /></div>
<p>Substituting back values of <img src="https://math.vercel.app/?from=x%20%3D%201%2B%5Crate" alt="x = 1+\rate" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=n%20%3D%20%5Cnper" alt="n = \nper" style="display: inline; vertical-align: middle;" />, we get.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cpmt%20%5Ctimes%20%5Cfrac%7B(1%2B%5Crate)%5E%7B%5Cnper%7D%20-%201%7D%7B%5Crate%7D" alt="\pmt \times \frac{(1+\rate)^{\nper} - 1}{\rate}" /></div>
<p>That gives us contribution from <img src="https://math.vercel.app/?from=%5Cpmt" alt="\pmt" style="display: inline; vertical-align: middle;" />. Now let's look at the whole equation again.</p>
<p>Why does the sum equal to <img src="https://math.vercel.app/?from=0" alt="0" style="display: inline; vertical-align: middle;" />?. My understanding is that it's a convention. You can think of it as putting some money in an investment, and after some time, taking everything out. The amount in the investment should be 0.</p>
<h3>IRR, NPV, XIRR, XNPV calculations</h3>
<p><a href="https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html">OpenOffice Document Format</a> documents functions on irregular cashflows in regular periods (<a href="https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#NPV">NPV</a>, <a href="https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#IRR">IRR</a>), and irregular cashflows in irregular periods (<a href="https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#XNPV">XNPV</a>, <a href="https://docs.oasis-open.org/office/OpenDocument/v1.3/os/part4-formula/OpenDocument-v1.3-os-part4-formula.html#XIRR">XIRR</a>). To understand calculations for these, it helps to understand NPV first. I might add the explanation here, in future. But till then, you could try <a href="https://www.investopedia.com/terms/n/npv.asp">investopedia explanation</a>. IRR is the rate at which NPV is 0. And similarly, XIRR is the rate at which XNPV is 0.</p>
<h2>Conclusion</h2>
<p>This picture and a mental model around what it means, should help you remember many of the financial functions in most excel implementations.</p>
<h2>Acknowledgement</h2>
<p>Thanks to <a href="https://ananthakumaran.in/">Anantha Kumaran</a> for feedback.</p>]]></content:encoded>
    </item>
    <item>
      <title>A Visual Exploration of Indian Population</title>
      <description>An example of data and perception guiding the design of a visualization, of India&apos;s 2011 population census.</description>
      <link>https://ciju.in/writings/population-census-2011-a-visualization</link>
      <guid isPermaLink="true">https://ciju.in/writings/population-census-2011-a-visualization</guid>
      <pubDate>Tue, 08 Feb 2022 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <media:content url="https://ciju.in/images/population.png" medium="image" />
      <media:thumbnail url="https://ciju.in/images/population.png" />
      <content:encoded><![CDATA[<p>import {diffColor, adultLineColor, maxStatePop, ageAggStats, gridMap, genderRatioLimit, areaBarColor, popBarColor} from '../src/population_vis/IndiaSplit.jsx';
import ColorSqr from '../src/population_vis/ColorSqr.jsx';</p>
<p>export const mColor = "#E7FEFE";
export const fColor = "#FCE8E8";
export const state = "Madhya Pradesh";</p>
<blockquote>
<p>Far better an approximate answer to the right question, which is often vague, than an exact answer to the wrong question, which can always be made precise. 
– <em>John W. Tukey</em>, The future of data analysis</p>
</blockquote>
<p>Asking good questions, for a data-set, is usually not straight forward. E.g. Which Indian states had more women than men (considering 2011 Indian census). Answer Kerala and Puducherry. But it's just a vanity metricsYet still, quite prevalent. E.g YouTube has many <a href="https://www.youtube.com/results?search_query=indian+demography">videos on Indian demography</a> with this and other vanity metrics, and no sign of deeper thinking.. More interesting is to ask, why? Why do these states have more women than men? And how does it compare to rest of the states? But more generally, what can help with having better questions?</p>
<p>Data visualizations are one way to come up with good questionsThere are other ways, like statistical analysis. But I don't know enough to dwell on them.. Our visual system is good at picking up certain kinds of patterns. Visualizations attempt at making it easier for eyes (and brain) to notice interesting patterns and anomalies in data. Patterns and anomalies in turn raise questions. This article is one example of designing visualization with our visual perception in mind. We will visualize India's 2011 population census.</p>
<p>An interactive version of the visualization is at the end of this article. Meanwhile here is an image of the visualization:</p>
<p>This is a dense visualization. But revealing many patterns and anomalies. It takes some effort to interpret, but leads to many questions around the data. I will go through the visualization and reasoning behind it, and keep the observations and questions for another article.</p>
<p>But before getting into the visualization, let's look at the data we will be working with.</p>
<h3>It starts with <em>data</em></h3>
<p>India conducts <a href="https://en.wikipedia.org/wiki/Census_of_India">census</a> every 10 year or so. Last census was in 2011I was hoping we would have 2021 census data by now. But it might be <a href="https://en.wikipedia.org/wiki/2021_Census_of_India#:~:text=It%20has%20been%20delayed%20to%202022%20due%20to%20the%20COVID%2D19%20pandemic%20in%20India%5B5%5D%20with%20preliminary%20results%20expected%20in%202023%E2%80%9324.%5B6%5D">another few years (2024)</a> for the next census data to be available.. The 2011 censusData available at: <a href="https://www.censusindia.gov.in/2011-Common/CensusData2011.html">https://www.censusindia.gov.in/2011-Common/CensusData2011.html</a> recorded more detailed than previous ones. Of particular interest for this post, 2011 census recorded population by age.</p>
<p>In this article, we will explore the age population distribution at state level. The Indian census for 2011 has data at district level, but to save effort, this post only considers state level data. The original data is from <a href="https://www.censusindia.gov.in/2011-Common/CensusData2011.html">census portal</a>Converted to <a href="https://github.com/ananthakumaran/visualization/blob/master/population/age/data/age.csv">csv here</a> with a <a href="https://github.com/ananthakumaran/visualization/blob/master/population/age/Makefile">script</a>, thanks to <a href="https://ananthakumaran.in/">Anantha Kumaran</a>.. As an example, here are a few entries from the data that we will be trying to visualize.

Few notes about the data:</p>
<ul>
<li><strong>100+</strong>: People aged 100 and above are counted in a single age bucket of 100+.</li>
<li><strong>Unknown</strong>: A small subset of the population has <em>Age not mentioned</em>, whatever that means. We will skip these for simplicity.</li>
<li><strong>Gender</strong>: The 2011 census seems to have clubbed all non-binary population into <em>Other</em>. About half a million people in total, identified as <em>Other</em>. For simplicity, we will only consider binary genders (female &#x26; male).
<ul>
<li><a href="https://www.downtoearth.org.in/blog/governance/non-binary-genders-need-more-visibility-in-india-s-census-2021-78844">Non-binary genders need more visibility in India’s Census 2021 · <em>Anuj Behal</em></a></li>
<li><a href="http://paa2019.populationassociation.org/uploads/190235">‘Other’ Gender in India: An Analysis of 2011 Census Data · <em>Chaitali Mandal</em></a></li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th>State</th>
<th align="right">Age</th>
<th align="right">Female population</th>
<th align="right">Male population</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bihar</td>
<td align="right">20</td>
<td align="right">1,110,387</td>
<td align="right">1,239,346</td>
</tr>
<tr>
<td>Jammu &#x26; Kashmir</td>
<td align="right">30</td>
<td align="right">152,274</td>
<td align="right">163,327</td>
</tr>
<tr>
<td>Jammu &#x26; Kashmir</td>
<td align="right">99</td>
<td align="right">394</td>
<td align="right">285</td>
</tr>
</tbody>
</table>
<p>Visualization would also show area of the states, which is again sourced from  <a href="https://censusindia.gov.in/2011census/A-1_NO_OF_VILLAGES_TOWNS_HOUSEHOLDS_POPULATION_AND_AREA.xlsx">census data</a>.</p>
<h2>Visualizing data</h2>
<p>Give a data set, two people are likely to come up with different visualizations, if they go beyond standard bar chart, line chart etc. The space of possible visualizations is big. Even an individual might try many possibilities before deciding on one. Instead of bringing up whole space of my exploration, I will only bring my choices and reasoning behind them.</p>
<h3>Population count by age</h3>
<p>There are 4 dimensions/attributes we are going to explore. State, age, gender (male/female), size of population. We will start by picking a state (<em>{state}</em> again) and charting age vs population (and add gender later)After we go through visualization for one state, we will use  small multiples to visualize all of them together..</p>
<p>To compare the states better, We will also include the total population and area of states, in the chart. We could show the absolute values for both, but it would be difficult to discern pattern out of totals. Instead, I decided to show the population relative to the most populous state (<em>Uttar Pradesh, 200 million</em>), and are relative to the state having largest area (<em>Rajasthan, 350k  km²</em>). Area is shown in brown  and population in green  lines on top of the chart. Again for perception, these lines have markers. Breaking the line to 10 parts. Each part signifies <img src="https://math.vercel.app/?from=%5Cfrac%7B1%7D%7B10%7Dth" alt="\frac{1}{10}th" style="display: inline; vertical-align: middle;" /> of the maximum. E.g The population line for {state} looks like . It has about 3½ green parts. Which means, it's about <img src="https://math.vercel.app/?from=%5Cfrac%7B3.5%7D%7B10%7D" alt="\frac{3.5}{10}" style="display: inline; vertical-align: middle;" /> times the population of UP. And in case of area, {state} is about <img src="https://math.vercel.app/?from=%5Cfrac%7B9%7D%7B10%7Dth" alt="\frac{9}{10}th" style="display: inline; vertical-align: middle;" /> of Rajasthan.</p>
<p>This concludes out introduction to the visualization. Now let's look at how the overall population of India, looks in this visualization.</p>
<h2>Visualizing India</h2>
<p></p>
<p>I will share my observations in another article, except for one around the gender gap. It's interesting that on average, fewer girls are born compared to boys. But that bias in sex ratio doesn't seem to there for older population. Do women survive longer than men? Or was there less birth sex bias in older generations?</p>
<p>More troubling is the number of missing girls. Hover over the chart and you will notice that about 1 million more men were born, compared to women, for each age, till about 25. That's 25 million missing women, below the age of 25. To get a perspective on it, compare it with Bangalore population in 2021. It's estimated to be <a href="https://www.macrotrends.net/cities/21176/bangalore/population">13 million</a>. The missing population is about twice the population of Bangalore. Since there is a biological bias for boys, we can't make a conclusion with just this data. Fortunately, we have state level data, to gain more context on this.</p>
<h2>Visualizing states of India</h2>
<p>Now let's look at the states in India, in 2011.Since then, <em>Telangana</em> was separated from <em>Andhra Pradesh</em>. <em>Jammu &#x26; Kashmir</em> was split into two union territories: <em>Jammu &#x26; Kashmir</em> and <em>Ladakh</em>. And Union Territory of <em>Daman and Diu</em> and the Union Territory of <em>Dadra and Nagar Haveli</em> were merged into one Union Territory: the Union Territory of <em>Dadra and Nagar Haveli and Daman and Diu</em>. ― Proposed states and union territories of India
· <em>Wikipedia</em></p>
<p>The states and union territories are visualized as <a href="https://en.wikipedia.org/wiki/Small_multiple">small multiples</a>
States are mapped on a grid, based approximately on their geographic location, with some artistic freedomThanks to <a href="https://saneef.com">Saneef</a> for the idea and the <a href="https://observablehq.com/@saneef/states-of-india-grid-map-data">mapping</a>.. This way, it is easy to compare neighboring states. Or gain a sense of trends, based on region. Again, the shades of green represent the percentage of population in that age. Darker green for higher percentage. You can click on a state to expand it, and click again to bring it back to it's original size.</p>
<p>I will cover the one question we started with. The states with more females than males. Kerala and Puducherry. Birth ratio in both of them, seems to similar to most other states. In case of Kerala, seems like a portion of adult male population is missing. Likely the <a href="https://en.wikipedia.org/wiki/Kerala_Gulf_diaspora">Gulf affect</a>. In other words, men are outside, for work. Likely having their wives take care of family. Let's consider Puducherry. Puducherry seems to have population peak in adult age, both male and female. But there are more adult females, than males. I haven't figured out why. Maybe, Puducherry has more women tourists than men? But note that the population is really small to consider it as a significant affect.</p>
<p>There is a lot to observe, and many questions to explore. For example, how does the birth ratio change across states. What are the different shapes for population distribution. Differences based on region. Etc. But enough for this article. I will cover my observations in another article.</p>
<h2>Closing thoughts</h2>
<p>Better understanding of perception is useful for better visualization. One I use often, is that we like comparisons, not absolutes. There are many more. If you are interested in exploring perception for visualization, here are a few resources I have read/seen (or am planning to read/watch).</p>
<ul>
<li><a href="https://scholar.google.co.in/scholar?q=The+Science+of+Visual+Data+Communication:+What+Works">The Science of Visual Data
Communication: What Works  · <em>Steven L. Franconeri</em>, <em>Lace M. Padilla</em>, <em>Priti Shah</em>,
<em>Jeffrey M. Zacks</em>, and <em>Jessica Hullman</em></a></li>
<li><a href="https://scholar.google.com/scholar?q=Algebraic+Visualization+Design+for+Pedagogy">An Algebraic Process for Visualization Design · <em>Gordon Kindlmann</em>, <em>Carlos Scheidegger</em></a></li>
<li><a href="https://arxiv.org/abs/2107.07477">A Survey of Perception-Based Visualization Studies by Task · <em>Ghulam Jilani Quadri</em>, <em>Paul Rosen</em></a> with accompanying <a href="https://usfdatavisualization.github.io/VisPerceptionSurvey/index.html">site</a></li>
<li><a href="https://www.youtube.com/watch?v=IiF4-g001EQ">Everything is Seasonal · <em>Zan Armstrong</em></a></li>
<li><a href="https://stackoverflow.blog/2022/03/03/stop-aggregating-away-the-signal-in-your-data/">Stop aggregating away the signal in your data · <em>Zan Armstrong</em></a></li>
<li><a href="https://www.youtube.com/watch?v=W02ZlvulHSY">Three Simple, Flexible Tools for Empowered Data Visualization · <em>Zan Armstrong</em>, <em>Outlier 2022</em></a></li>
<li><a href="https://www.csc2.ncsu.edu/faculty/healey/PP/">Perception in Visualization · <em>Christopher G. Healey</em></a></li>
</ul>
<h2>Acknowledgement</h2>
<p>Thanks to <a href="https://ananthakumaran.in/">Anantha Kumaran</a>, <a href="https://saneef.com/">Saneef</a>, <a href="https://rahulj.dev/">Rahul</a> for help with data and feedback on the article.</p>]]></content:encoded>
    </item>
    <item>
      <title>Cosmic Scales</title>
      <description>On playing with few numbers, to gain a perspective on cosmos.</description>
      <link>https://ciju.in/writings/a-play-with-universe</link>
      <guid isPermaLink="true">https://ciju.in/writings/a-play-with-universe</guid>
      <pubDate>Wed, 19 Jan 2022 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>Our universe is <a href="https://en.wikipedia.org/wiki/Age_of_the_universe">14 billion years old</a>. With <img src="https://math.vercel.app/?from=100%5C%20billion" alt="100\ billion" style="display: inline; vertical-align: middle;" /> galaxies in observable universe. And on average of <img src="https://math.vercel.app/?from=100%5C%20billion" alt="100\ billion" style="display: inline; vertical-align: middle;" /> stars in a galaxy. Spanning about <img src="https://math.vercel.app/?from=43%5C%20billion%5C%20%5Ctext%7Blight-years%7D" alt="43\ billion\ \text{light-years}" style="display: inline; vertical-align: middle;" /> around us. The scales we deal with in our <a href="https://www.youtube.com/watch?v=XFV2feKDK9E&#x26;t=103s">day-to-day</a> <a href="https://youtu.be/Q6Gw08pwhws?t=65">life</a>, are much smaller in comparison. How do we appreciate the cosmic scale?</p>
<p>If I did my job rightI am new to these numbers and the approach. If you find mistakes, please do let me know., reading this article, you would have gained a few analogies to work with cosmic numbers. Among other things, you would find that if the <img src="https://math.vercel.app/?from=14%5C%20billion%5C%20year" alt="14\ billion\ year" style="display: inline; vertical-align: middle;" /> history of universe is squished into <img src="https://math.vercel.app/?from=72%5C%20years" alt="72\ years" style="display: inline; vertical-align: middle;" />, most of human advancement happened in last minute. That if we squish a galaxy into the volume of a human being, about million stars would fit in <img src="https://math.vercel.app/?from=1%5C%20%5Ctext%7Bcentimeter%7D" alt="1\ \text{centimeter}" style="display: inline; vertical-align: middle;" /> cube. But the star themselves would be smaller than the size of an atom. i.e, most of the space is empty. And that at this scaling, next galaxy would be <img src="https://math.vercel.app/?from=25%5C%20meters" alt="25\ meters" style="display: inline; vertical-align: middle;" /> away.</p>
<p>Experiencing these scales is out of question. But we can build some familiarity and anthropomorphized sense for these scales. Two activities that I have found useful are <strong>analogy</strong>For the analogies to work, we have map the numbers to human range. I haven't considered error margins in the calculations. And haven't spent enough effort to be precise. I think it won't be an issue. and <strong>playing with the numbers</strong>. To get familiar with numbers, you would have to play with them, yourself. Analogies are easier to share and build upon. <strong>This article plays with a few cosmic numbers and shares analogies around them, that I have found interesting</strong>.</p>
<p>We will get help from a fictitious Celestial Being, referred to as <strong>CB</strong> in the article, for some of our analogies. And give itTo avoid <a href="https://www.theguardian.com/science/2019/aug/05/he-she-or-gender-neutral-pronouns-reduce-biases-study">gender pronoun argument</a> about the celestial being, let's use <em>it</em> to refer to the being. I assure you, <em>it</em> doesn't mind. some supernatural, but limited powers. First power it has is to be able to create universes, as an experiment. Something akin to <a href="https://en.wikipedia.org/wiki/Petri_dish">petri-dish experiments</a>, but at a much grander scale. We will look at CB's perspective on one such experiment (our universe) and our place in it.</p>
<p>We start with <em><strong>time</strong></em>. It's been 14 billion years, since the <a href="https://en.wikipedia.org/wiki/Big_Bang">Big Bang</a>What happened before then, is CB's concern. when CB started the experiment.</p>
<h2>Time</h2>
<p>Here is CB's another supernatural power. For it, time seems to be passing much faster. CB started the experiment 72 CB Years ago, with a <a href="https://en.wikipedia.org/wiki/Big_Bang">Big Bang</a>. 1 CB year is equivalent to &#x3C;OverNote inlineContent={"194 million human years"} overContent={ } /> . A CB year has days, hours, minutes, seconds, same as an Earth for humans1 year is not special from universe perspective. Neither is 1 second. Year is rotation of earth around sun. And second is a convention (or standard?). I use same notion of year and second for CB, to make things more palatable for our mind.. In other words, 1 CB second is about &#x3C;OverNote inlineContent={"6 years"} overContent={Since 72 CB Years is approximately equal to 14 billion human years. 1 CB second is about  or about 6 human years.} /> for humans. We get a year older, and for CB not even a second has passed. In rest of the section, assume all time-scales are CB's perspective, unless explicitly mentioned as human time-scale.</p>
<p>Average human life of 72 years, in CB's time would be &#x3C;OverNote inlineContent="12 seconds" overContent={Average human life expectancy is 72 years. 72 human years, would be about   or 12 CB seconds.} />. So, for CB, here is how timeline of our history would feel like:</p>
<ul>
<li>It's been 72 years since experiment started (with a Big Bang). Or the Universe is 72 years old.</li>
<li>Earth appeared roughly &#x3C;OverNote inlineContent="23 year" overContent={4.5 billion years ago.   or 22 years 5 months in CB's timeline, since experiment start.} /> after Big Bang. Ignoring rest of the universe and focusing on earth.
<ul>
<li>First life appeared &#x3C;OverNote inlineContent={"53 years"} overContent={3.7 billion years ago. } /> after Big Bang or 19 years ago.</li>
<li>Dinosaurs lived and went extinct in &#x3C;OverNote inlineContent={"year 69"} overContent={Dinosaurs lived somewhere between 245 and 66 million years ago.  -   1 year 2 month - 4 months} />.</li>
<li>When did <a href="https://en.wikipedia.org/wiki/Homo">human genus</a> come into picture? <strong>Around year</strong> &#x3C;OverNote inlineContent={70} overContent={Our ancestors appeared around 2 million years algo. } /> <strong>(just 2 years ago from CB's perspective)</strong>.</li>
<li>Our species, Homo Sapiens, only emerged around &#x3C;OverNote inlineContent={14 hours ago} overContent={Homo Sapiens emerged around 300,000 to 200,000 human years ago. Remember, 1 CB second is about 6 human years. So, Homo Sapiens emerged  ago. Or, about 14 CB hours.} />.</li>
<li>Most of <a href="https://en.wikipedia.org/wiki/Recorded_history">written human history</a>, around 4000 human years, would be about 11 minutes for CB.</li>
<li>In last &#x3C;OverNote inlineContent={"30 seconds"} overContent={"About 200 human years."} /> , humans learned that the solar system is part of a galaxy with 100 billion stars. And their galaxy is also nothing special but another in 100 billion or so galaxies. And are contemplating the origins of the experiment and much more.</li>
</ul>
</li>
</ul>
<p>It's fascinating to think how much has happened in last minute, from CB's perspective. Be it the understanding of what is within reach (nature), what is beyond/before/after (universe), what can be (AI, large societies, maths, space exploration) and much more. Human beings have expanded their understanding exponentially, in as many topics.</p>
<p>But, for CB to observe this, it would have to find Earth first. The planet where humans are. A planet, in a solar system, in a galaxy, in the universe.</p>
<h2>Counting Stars</h2>
<p>We will start by first getting a sense of the number of stars in the universe. Earth is part of a solar system with other planets and one star (Sun). Sun is one among 100 billion other stars in the Mikly Way galaxy. Milky Way itself is one among 100 billion galaxies in the universeThat we know these numbers is in itself interesting. So, in total, 100 billion * 100 billion stars in the universe. Building intuition around this number is going to be difficult. But let's play with these numbers.</p>
<p>First let's get some familiarity with <em>billion</em>.</p>
<h3>Few billions</h3>
<p>Human population around 9 billion right now. Let’s give each person 1 meter and make them stand one beside another, in a line. How long would that line be? That line could <a href="https://en.wikipedia.org/wiki/Earth&#x27;s_circumference">circle the earth</a> &#x3C;OverNote inlineContent={"200 times"} overContent={  or   } /> . If you could <a href="https://en.wikipedia.org/wiki/Preferred_walking_speed">walk</a> (without sleep) at 5 km/hour you can cover the circumference in 8000, or about a year (with few short breaks). What would be your age, 1 billion seconds after you are born? Answer: About 31 years, 6 months. Assuming 72 years as average age, most of us live about 2.27 billion seconds. Shake hands with one person for 1s, how long will it take to shake hand with all the humanity. That would be about 253 years. Definitely not something we have intuitive sense of. But, gives us a reference point to play with the number of stars in the universe.</p>
<h3>Back to stars</h3>
<p>Let's give CB another super-power, with limitation. It sees galaxies as we see our bodyHere is another fascinating scale. Our body houses around 30 trillion cells.. As an example, Milky Way galaxy filling a persons body. I will call this <em>galaxy bodies</em>. One galaxy is one <em>galaxy body</em>. Observable universe is <img src="https://math.vercel.app/?from=100%5C%20billion" alt="100\ billion" style="display: inline; vertical-align: middle;" /> galaxies. Or about &#x3C;OverNote inlineContent={} overContent={"Rounding human population to 10 billion. 100 billion galaxies is 10 times that."} /> times the human population.  In total there would be about 10 times human population <em>galaxy bodies</em>100 billion galaxies, round human population to 10 billion. That means about 10 times as many galaxies as humans.</p>
<p>Now consider all the stars in one <em>galaxy body</em>. That’s 100 billion stars packed one besides other, in our body. Imaging a small centimeter cube on your fingertip, that would be around &#x3C;OverNote inlineContent={"1 million stars"} overContent={One way to calculate this is first get volume of human body, in  and divide the number of stars in a galaxy with it. First, volume of human body. One way is to calculate it with density and mass of human body. Let's say average mass is 75 kg and density close to . So volume comes out to be  or . Converting to centimeters . Dividing number of stars in a galaxy with the volume,  or . A million stars in a centimeter cube.} />. We are ignoring distance between the stars. We will look at distances in next section.</p>
<p>So, Earth would be somewhere in the Milky Way <em>galaxy body</em>. Let's say at the tip of a finger. CB doesn't know where exactly to look, so it will have to look one star at a time (given no waves or communication). Let's hope for the fictitious entities' sake, there are more planets with lifeSee: <a href="https://inference-review.com/article/a-lonely-universe">https://inference-review.com/article/a-lonely-universe</a>.</p>
<p>But if only earth has life, assuming the celestial being can scan 1 star a CB second, a <em>galaxy body</em> would take it around &#x3C;OverNote inlineContent={ } overContent={1 second per star. 100 billion stars. So, 100 billion seconds. That is about 3000 years.} /> . That's 1 galaxy. Even if we assume that CB would find Sun after groing through half of the <em>galaxy bodies</em>, it will still take &#x3C;OverNote inlineContent={ } overContent={ } />  to find Sun. The being would have to be immortal, with abundant patience. Hope the human race survives that long.</p>
<p>But that's not the only concern. Stars are not packed together, like cells in the body. There is a lot of space between them.</p>
<h3>Space</h3>
<p>Within the <em>galaxy body</em>, if we scale the stars in proportion to the space available to them, the size of the stars would be about <img src="https://math.vercel.app/?from=10%5E%7B-9%7D%5C%20cm" alt="10^{-9}\ cm" style="display: inline; vertical-align: middle;" />. That is smaller than an <a href="https://en.wikipedia.org/wiki/Atomic_radii_of_the_elements_(data_page)">atom</a>. I.e. most of the space inside <em>galaxy body</em> is empty. Yet, there are a million stars in it. On the other hand, if CB looks for neighboring <em>galaxy bodies</em>, they would be around <img src="https://math.vercel.app/?from=25%5C%20m" alt="25\ m" style="display: inline; vertical-align: middle;" /> away. At the scale of stars, space is mostly empty. But at the scale of galaxies, space is quite packed. And all of the observable universe would have a width of &#x3C;OverNote inlineContent={ } overContent={Observable universe is  wide. We are mapping  wide galaxies to about  . So, universe would be  wide. Or about   wide. } />. Let's work this out step by step.</p>
<p>Moon is about <img src="https://math.vercel.app/?from=400%2C000%5C%20km" alt="400,000\ km" style="display: inline; vertical-align: middle;" /> away from Earth. That's big enough to fit in &#x3C;OverNote inlineContent={"30 Earths"} overContent={Earth diameter is . Diving distance by Earth's diameter, , or about  Earths.} />. Sun is <img src="https://math.vercel.app/?from=150%20%5Ctimes%2010%5E6%5C%20km" alt="150 \times 10^6\ km" style="display: inline; vertical-align: middle;" /> away from Earth. <a href="https://en.wikipedia.org/wiki/Proxima_Centauri">Proxima Centauri</a>, Sun's nearest neighboring star, is <img src="https://math.vercel.app/?from=4%20%5Ctimes%2010%5E%7B13%7D%20%5C%20km" alt="4 \times 10^{13} \ km" style="display: inline; vertical-align: middle;" /> away. It's going to be difficult to deal with distances in <img src="https://math.vercel.app/?from=km" alt="km" style="display: inline; vertical-align: middle;" />.</p>
<p>Instead, astronomical distances are mostly measured in light-yearsThere is also <a href="wikipedia.org/wiki/Astronomical_unit">AU</a> and cool-sounding <a href="https://wikipedia.org/wiki/Parsec">parsec</a>. You should check them out.. Let's start with speed of light. Light travels at about <img src="https://math.vercel.app/?from=300%2C000%5C%20km%2Fs" alt="300,000\ km/s" style="display: inline; vertical-align: middle;" />, or <img src="https://math.vercel.app/?from=3%20%5Ctimes%2010%5E8%5C%20m%2Fs" alt="3 \times 10^8\ m/s" style="display: inline; vertical-align: middle;" />. Speed of light is the fastest speed that can be achieved in our universeWith consequences like special relativity. Another fascinating topic to explore. Cars do about <img src="https://math.vercel.app/?from=100%5C%20km%2Fhour" alt="100\ km/hour" style="display: inline; vertical-align: middle;" /> or <img src="https://math.vercel.app/?from=0.03%5C%20km%2Fs" alt="0.03\ km/s" style="display: inline; vertical-align: middle;" />. Fastest speed a man-made object has achieved is about <img src="https://math.vercel.app/?from=700%2C000%5C%20km%2Fhour" alt="700,000\ km/hour" style="display: inline; vertical-align: middle;" />, or <img src="https://math.vercel.app/?from=200%5C%20km%2Fs" alt="200\ km/s" style="display: inline; vertical-align: middle;" />. It's a <a href="https://en.wikipedia.org/wiki/Parker_Solar_Probe">probe in space</a>. And it's only <img src="https://math.vercel.app/?from=0.065%5C%25" alt="0.065\%" style="display: inline; vertical-align: middle;" /> of the speed of light.</p>
<p>What does speed of light have to do with measuring space? Light from moon takes 1.3 seconds to reach earth, covering <img src="https://math.vercel.app/?from=400%2C000%5C%20km" alt="400,000\ km" style="display: inline; vertical-align: middle;" />. Light takes about 8 minutes to reach from Sun to earth, covering <img src="https://math.vercel.app/?from=150%20%5Ctimes%2010%5E6%5C%20km" alt="150 \times 10^6\ km" style="display: inline; vertical-align: middle;" />. Light-year is the distance light travels in a year31 million seconds in a year. So, light travels <img src="https://math.vercel.app/?from=31%20%5Ctimes%2010%5E6%20%5Ctimes%203%20%5Ctimes%2010%5E5" alt="31 \times 10^6 \times 3 \times 10^5" style="display: inline; vertical-align: middle;" /> or about <img src="https://math.vercel.app/?from=10%5E%7B13%7D%5C%20km" alt="10^{13}\ km" style="display: inline; vertical-align: middle;" /> in a year.. Light takes <img src="https://math.vercel.app/?from=4.2%5C%20years" alt="4.2\ years" style="display: inline; vertical-align: middle;" /> to reach from Proxima Centauri to Sun, covering <img src="https://math.vercel.app/?from=4%20%5Ctimes%2010%5E%7B13%7D%20%5C%20km" alt="4 \times 10^{13} \ km" style="display: inline; vertical-align: middle;" />. I.e. Proxima Centauri is <img src="https://math.vercel.app/?from=4.2%5C%20%5Ctext%7Blight-years%7D" alt="4.2\ \text{light-years}" style="display: inline; vertical-align: middle;" /> away from Sun.  Using <img src="https://math.vercel.app/?from=%5Ctext%7Blight-years%7D" alt="\text{light-years}" style="display: inline; vertical-align: middle;" /> makes cosmic distances easier to deal with. After all, light from the stars and galaxies, is how we know what we know about the universe. Now we are ready to look at cosmic distances.</p>
<p>Let's assume stars, <a href="https://www.space.com/57-stars-formation-classification-and-constellations.html#:~:text=Stars%20range%20in%20size%20from,is%20proportional%20to%20radius%20squared.">on average</a>, are the size of Sun. About <img src="https://math.vercel.app/?from=10%5E6%5C%20km" alt="10^6\ km" style="display: inline; vertical-align: middle;" /> in diameter. And separated from closest star by let's say <a href="https://en.wikipedia.org/wiki/Star#Distribution">5 light-years</a>. For these cases, the distance between stars is about &#x3C;OverNote inlineContent={ } overContent={ or . About    } />  times the size of the stars. If stars were a meter in diameter, their next neighbor would be about <img src="https://math.vercel.app/?from=10%2C000%5C%20km" alt="10,000\ km" style="display: inline; vertical-align: middle;" /> away. For comparison, earth diameter is <img src="https://math.vercel.app/?from=12%2C742%5C%20km" alt="12,742\ km" style="display: inline; vertical-align: middle;" />.</p>
<p><a href="https://en.wikipedia.org/wiki/Milky_Way#:~:text=estimated%20visible%20diameter%20of%20100%2C000%E2%80%93200%2C000%20light%2Dyears.">Milky Way galaxy</a> is  in diameter. And about 2.5 million light-years from Andromeda Galaxy. Again, I will assume this is somewhat representative of rest of the galaxies on average. The distance between galaxies is about &#x3C;OverNote inlineContent={} overContent={} /> times the size of galaxies. If galaxies were a meter in diameter, their next neighbor would be 25 meters away. Galaxies are quite close to each other.</p>
<p>Now consider <a href="https://en.wikipedia.org/wiki/Observable_universe">observable universe</a>. It's <strong>93 billion light-years</strong> wide.  It is related to how old the universe is. The theory is, universe as we know it, started with a big bang, and has been expanding ever since. And we are seeing edges of that universe, with what light could travel in that time. So,  universe might be much bigger than whats we can observe.</p>
<p>We figured in last section that a centimeter wide cube in our fictional <em>galaxy body</em> would have about 1 million stars in a <em>galaxy body</em>. Or on an edge of cube, there would be 100 stars, one after the other. Each star has <img src="https://math.vercel.app/?from=0.01%5C%20cm" alt="0.01\ cm" style="display: inline; vertical-align: middle;" /> to it. If we scale the star so that <img src="https://math.vercel.app/?from=0.01%5C%20cm" alt="0.01\ cm" style="display: inline; vertical-align: middle;" /> represents the distance between stars, the size of the star itself would be <img src="https://math.vercel.app/?from=10%5E%7B-9%7D%5C%20cm" alt="10^{-9}\ cm" style="display: inline; vertical-align: middle;" /> in diameter. That is smaller than size of an atom. In other words the 1 cm cube is mostly empty, but still there are 1million stars in it. On the other hand, like we saw in previous paragraph. If the galaxy is 1 meter in diameter, neighboring galaxy would be 25 meters away.</p>
<p>Imagine CB trying to find a planet around a sun (which is barely the size of an atom) in some galaxy body, among 100 billion galaxy bodies. CB would need a lot more super-powers than what we have given it.</p>
<h2>Before we part ways</h2>
<p>There is much more to explore. Galaxies are moving. Sometimes through each other. Imagine <em>galaxy bodies</em> moving through each other, while distoring each others shape because of gravity. There are planets, stars in different sizes (neutron stars, red giants), black-holes, Nebulae, galaxy clusters and much much more. Worth reading something like <a href="https://www.amazon.in/Welcome-Universe-Neil-Degrasse-Tyson/dp/0691157243/">Welcome to the Universe: An Astrophysical Tour</a>, to know more.</p>
<p>My intent with this post, was to share some examples of scaling to human range. I find playing with numbers helps in getting familiar with them. Hopefully, this write-up will nudge you towards exploring on your own, if you haven't already.</p>
<p>But I can't stop without pointing out the wonder of our existence. Universe itself is fascinating, on how it came to be, what it is, what it's going to be. The basic elements it's made of, lead to planets and sun. Life happened on at least one of these planets. With all its variety and process, life (or evolution) is fascinating in its own right. Somehow this process created intelligence which can observe and grow new super-powers (technology for both observation and affect) and gain some understanding of both universe and the process of life itself. This is not even scratching the surface of what we have achieved as a species.</p>
<h2>Further explorations</h2>
<p>Two broad areas that this article covers is playing with numbers and scale of universe.</p>
<h3>Playing with numbers</h3>
<p>For playing with numbers, here are a few books that you might find interesting.</p>
<ul>
<li>Chapter 6. <strong>On Number Numbness</strong> - <a href="https://www.amazon.com/Metamagical-Themas-Questing-Essence-Pattern/dp/0465045669">Metamagical Themas: Questing for the Essence of Mind and Pattern</a> - <em>Douglas R Hofstadter</em></li>
<li><a href="https://www.amazon.com/Innumeracy-Mathematical-Illiteracy-Its-Consequences/dp/0809058405">Innumeracy</a> - <em>John Allen Paulos</em></li>
<li><a href="https://www.amazon.com/Millions-Billions-Zillions-Defending-Yourself/dp/0691182779/">Millions, Billions, Zillions: Defending Yourself in a World of Too Many Numbers</a> - <em>Brian W. Kernighan</em></li>
<li><a href="https://www.amazon.com/Machinery-Life-David-S-Goodsell/dp/0387849246">The Machinery of Life</a> - <em>David S. Goodsell</em>
Cell biology is another fascinating area with scales difficult to experience. The Machinery of Life uses analogy and visualizations to introduce it.</li>
</ul>
<h3>Scale of universe</h3>
<ul>
<li><a href="https://www.amazon.in/Welcome-Universe-Neil-Degrasse-Tyson/dp/0691157243/">Welcome to the Universe: An Astrophysical Tour</a> - <em>Neil deGrasse Tyson</em>, <em>Michael A. Strauss</em>, <em>J. Richard Gott</em></li>
<li><a href="https://www.youtube.com/watch?v=e4zHfKBhnqM&#x26;list=PLEE8A6CB118FADED4&#x26;index=1">Cosmic Distance Ladder - videos</a></li>
<li><a href="https://www.youtube.com/watch?v=0fKBhvDjuy0">Powers of Ten™ (1977) - video</a> </li>
<li><a href="https://en.wikipedia.org/wiki/File:Expansion_of_the_universe,_comoving_coordinates_(Animation).gif">Expansion of the universe, comoving coordinates</a></li>
<li><a href="https://solarsystem.nasa.gov/news/1164/how-big-is-the-solar-system/">How big is the solar system</a></li>
<li><a href="https://www.youtube.com/watch?v=Iy7NzjCmUf0">How the Universe is Way Bigger Than You Think</a></li>
</ul>
<h2>Acknowledgement</h2>
<p>Thanks to <a href="https://ananthakumaran.in/">Anantha Kumaran</a>, Lalit Patel, <a href="https://rohitshinde.in/">Rohit Shinde</a>, <a href="https://saneef.com/">Saneef</a> and others for their feedback. Much of the blog is influenced by books, videos and writeups by others on the net. Infact, there might be no original idea in this article. Unfortunately, it's difficult to keep track of all the sources.</p>]]></content:encoded>
    </item>
    <item>
      <title>On Time, Clock and Ordering paper</title>
      <description>A fundamental paper, often misunderstood.</description>
      <link>https://ciju.in/writings/2021-09-on-time-clock-and-ordering-of-events</link>
      <guid isPermaLink="true">https://ciju.in/writings/2021-09-on-time-clock-and-ordering-of-events</guid>
      <pubDate>Thu, 16 Sep 2021 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p><a href="https://lamport.azurewebsites.net/pubs/time-clocks.pdf">Time, Clocks and Ordering</a> (TCO) paper is among the most referred paper in distributed systems. Often, summaries/discussions about the paper concentrate on the logical clock. Logical clock is an important contribution of the paper. But more interesting part is being able to implement arbitrary distributed state machines, given the no-failure assumption. Moreover, personally I find the paper to be a gateway drug to distributed systems. A way to give structure to some topics in distributed systems.</p>
<p>The paper shows how to <strong>implement an arbitrary state machine with distributed process, assuming there are no failures</strong>How does failure affect distributed systems. We will look at it briefly in the observations section.. Failures are unavoidable in real systems. Which makes this approach of deterministic distribute state machine impractical. Nevertheless the model used to prove the result is still quite useful.</p>
<blockquote>
<p>It didn't take me long to realize that an algorithm for totally ordering events could be used to implement any distributed system.  A distributed system can be described as a particular sequential state machine that is implemented with a network of processors. The ability to totally order the input requests leads immediately to an algorithm to implement an arbitrary state machine by a network of processors, and hence to implement any distributed system. <strong>So, I wrote this paper, which is about how to implement an arbitrary distributed state machine.</strong>  As an illustration, I used the simplest example of a distributed system I could think of a distributed mutual exclusion algorithm.</p>
<p>-- <em><a href="http://lamport.azurewebsites.net/pubs/pubs.html#time-clocks">27. Time, Clocks and the Ordering of Events in a Distributed System</a> (Emphasis mine)</em></p>
</blockquote>
<p>If you understand that statement, please feel free to jump to the <a href="#observations">observations</a> sections, and ignore rest of the article.</p>
<h2>The Model</h2>
<p>In the paper distributed system is modeled as a set of processes communicating with (passing messages to) each other. One way to make such a system deterministic, is to make parts of the systemin this case <strong>processes</strong> and <strong>communication</strong> deterministic and combine them in deterministic way.Are there other ways to make system deterministic? See <a href="#observations">observations</a> for some discussion. This statement might become clear as we go through the article.</p>
<p>Let’s consider <strong>processes</strong> first. How do we make processes deterministic? A common approach is to model processes as <a href="https://en.wikipedia.org/wiki/State_machine_replication">state machines</a>Determinism implies that the process can't read clocks or random numbers or cursor position etc. Or at least, they are modeled as input to the system. with messages as being the commands to the state machines. If you haven’t come across state machines, please do read the <a href="https://en.wikipedia.org/wiki/State_machine_replication">wiki</a> on it. The intuition is, given initial state, and same sequence of commands, state machine will reach the same state every time you execute it (it’s like a pure function over initial state and sequence of commands).</p>
<p>With processes being deterministic, the only non-determinism that remains in the system, is the order of messages. With network delays, when a message arrives is not deterministic. But, if we can make sure that all processes (which are state machines) execute messages (commands) according to a global order, then we would have a deterministic system. The algorithm is slightly more involved, and covered later in the article.</p>
<p>Before that, how do we get total order for messages. One way is to have a central server to sequence eventsThis is not a distributed algorithm, although, don't rule this out. Many practical distributed systems use some version of this.. Instead, and this is the most interesting part of the paper, the <strong>paper describes how we can have globally ordered events, with only local decisions</strong>. Thats the purpose of logical clocksCould we use real clocks (all computers have clocks) for ordering events? Well, yes and no. See <a href="#real-world-needs-clocks">Real world needs clocks</a> and <a href="#observations">observations</a> sections for more. . First few sections of the paper are about deriving logical clocks, to get global order for events. Which is then used to build a deterministic distributed mutual exclusion algorithm.</p>
<p>With the context in mind, here is roughly the structure of rest of the post (which mimics the paper).</p>
<ol>
<li><strong>Events</strong>
<ol>
<li><strong>Partial Ordering</strong> Define which orders need to be preserved. Paper calls these <strong>happened-before</strong> relations (e.g. all events in a process are ordered, and messages define ordering between processes).</li>
<li><strong>Logical Clocks</strong> Define properties that a logical clock would have to satisfy, to capture causality (the happened-before relations).</li>
<li><strong>Total Ordering</strong> Use logical clock and process ordering to get total order.</li>
</ol>
</li>
<li><strong>Deterministic Distributed System</strong> Use state machine processes and total ordering to define an algorithm for mutual exclusion without any central server or storage.</li>
</ol>
<p>I will conclude with some <strong>Observations</strong> around how it connects with other topics in Distributed systems.</p>
<h2>1. Events</h2>
<p>Events relevant for the paper, are the events around sending and receiving messages. For more details, please read the paper. You could also refer to a more formal coverage at <a href="https://mwhittaker.github.io/blog/lamports_logical_clocks/">Lamport's Logical Clocks</a>. In all the pictures below, time flows to the right and the horizontal lines represent the different processes (or humans).</p>
<h3>1.1 Partial Ordering</h3>
<p>First we need to understand which orders are important to preserve. There are primarily two cases. First, events happening in a single process, are ordered. E.g a user request message was received before the database query message being sent to another process. Second, if process <img src="https://math.vercel.app/?from=p_1" alt="p_1" style="display: inline; vertical-align: middle;" /> sends a message to process <img src="https://math.vercel.app/?from=p_2" alt="p_2" style="display: inline; vertical-align: middle;" />, intuitively, events that happened before <img src="https://math.vercel.app/?from=p_1" alt="p_1" style="display: inline; vertical-align: middle;" /> sends the message, should happen before, events in <img src="https://math.vercel.app/?from=p_2" alt="p_2" style="display: inline; vertical-align: middle;" /> after it has received the message. These causal relations are formalized in the paper, as below:</p>
<ol>
<li></li>
<li></li>
<li>If <img src="https://math.vercel.app/?from=a%20%5Crightarrow%20b" alt="a \rightarrow b" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b%20%5Crightarrow%20c" alt="b \rightarrow c" style="display: inline; vertical-align: middle;" /> then <img src="https://math.vercel.app/?from=a%20%5Crightarrow%20c" alt="a \rightarrow c" style="display: inline; vertical-align: middle;" />. Two distinct events <img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" /> are said to be <em>concurrent</em> if <img src="https://math.vercel.app/?from=a%20%5Cnrightarrow%20b" alt="a \nrightarrow b" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b%20%5Cnrightarrow%20a" alt="b \nrightarrow a" style="display: inline; vertical-align: middle;" />.</li>
</ol>
<p>Here is an example with two process communicating. <img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" /> sends a message <img src="https://math.vercel.app/?from=m_1" alt="m_1" style="display: inline; vertical-align: middle;" /> to <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" />, which after some processing, sends back message <img src="https://math.vercel.app/?from=m_2" alt="m_2" style="display: inline; vertical-align: middle;" /> to <img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" />. An event happened before another, is there is a sequence of happened before relations connecting them. Few relations: <strong><img src="https://math.vercel.app/?from=c%20%5Cnrightarrow%20b" alt="c \nrightarrow b" style="display: inline; vertical-align: middle;" /></strong> (there is no happened-before relation between <img src="https://math.vercel.app/?from=c" alt="c" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" />), <strong><img src="https://math.vercel.app/?from=c%20%5Cnrightarrow%20d" alt="c \nrightarrow d" style="display: inline; vertical-align: middle;" /></strong>, <strong><img src="https://math.vercel.app/?from=a%20%5Crightarrow%20d" alt="a \rightarrow d" style="display: inline; vertical-align: middle;" /></strong> (<img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" /> happened-before <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" />).
&#x3C;img style={{width: "100%", margin: "0 auto", padding: "1em", maxWidth: 500}} src="/images/tc-po-3.svg" /></p>
<h3>1.2 Logical Clocks</h3>
<p>The happened-before relations can be mapped to numbers (which are comparable). This would help with implementing them in real systems. The two conditions in the Logical Clocks section define the constraints that such representation should adhere to.</p>
<ul>
<li><strong>C1</strong> If <img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" /> are events in process <img src="https://math.vercel.app/?from=P_i" alt="P_i" style="display: inline; vertical-align: middle;" />, and <img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" /> comes before <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" />, then <img src="https://math.vercel.app/?from=C_i%20%5Clangle%20a%20%5Crangle%20%26%23x3C%3B%20C_i%20%5Clangle%20b%20%5Crangle" alt="C_i \langle a \rangle &amp;#x3C; C_i \langle b \rangle" style="display: inline; vertical-align: middle;" /></li>
<li><strong>C2</strong> If <img src="https://math.vercel.app/?from=a" alt="a" style="display: inline; vertical-align: middle;" /> is the sending of a message by process <img src="https://math.vercel.app/?from=P_i" alt="P_i" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" /> is the receipt of that message by process <img src="https://math.vercel.app/?from=P_j" alt="P_j" style="display: inline; vertical-align: middle;" />, then <img src="https://math.vercel.app/?from=C_i%20%5Clangle%20a%20%5Crangle%20%26%23x3C%3B%20C_j%20%5Clangle%20b%5Crangle" alt="C_i \langle a \rangle &amp;#x3C; C_j \langle b\rangle" style="display: inline; vertical-align: middle;" />.</li>
</ul>
<p>Now, what kind of mapping could work for this? Essentially, increment for any event within a process. and if a message is sent, increment before sending. The message itself carries the logical clock timestamp of the sending process. And the receiving process picks a time stamp greater than both the message and its current time stamp max(clock_in_msg, local_clock) + 1. This gives an ordering of the all the messages for which the order needs to be preserved.</p>
<p>Here is a mapping for the happened-before relation we saw earlier. Note that the timestamp for both <img src="https://math.vercel.app/?from=c" alt="c" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" /> is same, 2. This can happen for some of the events across processes, which are not related by happened-before. Which means, we still don't have total order.</p>
<p>&#x3C;img style={{width: "100%", margin: "0 auto", padding: "1em", maxWidth: 500}} src="/images/tc-po-mapping.svg" /></p>
<h3>1.3 Total order</h3>
<p>The few cases where timestamp might be same for events across processes (similar to last section), we need a deterministic way to order them. The approach paper uses is to have a pre-determined order for processes. So the total order is given by the pair (time-stamp, process_id). If the logical timestamp clashes, we break the tie with process_id. For the events below, if <img src="https://math.vercel.app/?from=p%20%26%23x3C%3B%20q" alt="p &amp;#x3C; q" style="display: inline; vertical-align: middle;" />, where <img src="https://math.vercel.app/?from=p" alt="p" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=q" alt="q" style="display: inline; vertical-align: middle;" /> are process_id for the respective processes, then the global order of events is <img src="https://math.vercel.app/?from=(1%2Cp)%20%5Crightarrow%20(2%2C%20p)%20%5Crightarrow%20(2%2Cq)%20%5Crightarrow%20(3%2Cq)%20%5Crightarrow%20(4%2Cp)" alt="(1,p) \rightarrow (2, p) \rightarrow (2,q) \rightarrow (3,q) \rightarrow (4,p)" style="display: inline; vertical-align: middle;" />
&#x3C;img style={{width: "100%", margin: "0 auto", padding: "1em", maxWidth: 500}} src="/images/tc-po-total-order.svg" />
To summarize, we have total order for all the messages and given two events, any process can derive their global order only based on their timestamps and the predefined order of processes.</p>
<h3>2. Deterministic Distributed System</h3>
<p>We are ready to combine this total order and state machines, to create an arbitrary state machine on a distributed system (set of processes). The paper shows this by implementing a distributed mutual exclusion algorithm.</p>
<p>You should read the paper for the algorithm, but here is my intuition. First the assumptionsAlthough, they might not be necessary. E.g. One can build a reliable messaging service (like tcp) over reliable processes.:</p>
<ol>
<li>Messages between two processes are received in order.</li>
<li>Messages are eventually delivered</li>
</ol>
<p>Moving on to the algorithm, the intuition that helps, is to look at the process locally. Consider a process <img src="https://math.vercel.app/?from=P_i" alt="P_i" style="display: inline; vertical-align: middle;" /> which has its request as the lowest timestamp on the request queue. Let's say the request has timestamp <img src="https://math.vercel.app/?from=ts_i" alt="ts_i" style="display: inline; vertical-align: middle;" />. Let's also consider another process <img src="https://math.vercel.app/?from=P_j" alt="P_j" style="display: inline; vertical-align: middle;" />. If <img src="https://math.vercel.app/?from=P_i" alt="P_i" style="display: inline; vertical-align: middle;" /> has received a message from <img src="https://math.vercel.app/?from=P_j" alt="P_j" style="display: inline; vertical-align: middle;" /> with timestamp greater than <img src="https://math.vercel.app/?from=ts_i" alt="ts_i" style="display: inline; vertical-align: middle;" />, then <img src="https://math.vercel.app/?from=P_i" alt="P_i" style="display: inline; vertical-align: middle;" /> can be sure that no other message with lower timestamp can come from <img src="https://math.vercel.app/?from=P_j" alt="P_j" style="display: inline; vertical-align: middle;" />. Similar logic applies to all the other processes. So, <img src="https://math.vercel.app/?from=P_i" alt="P_i" style="display: inline; vertical-align: middle;" /> executes its request, when its command has the lowest timestamp in the request queue and it has received messages with timestamp greater than <img src="https://math.vercel.app/?from=ts_i" alt="ts_i" style="display: inline; vertical-align: middle;" /> from all the processes.</p>
<p>Here is an example. The green events are the message send events for mutual exclusion request. The brown events are message send events after the mutually exclusive block. The green segment of process timeline signifies the time range where the command would be executed. For this example, let's assume <img src="https://math.vercel.app/?from=p%20%26%23x3C%3B%20q%20%26%23x3C%3B%20r" alt="p &amp;#x3C; q &amp;#x3C; r" style="display: inline; vertical-align: middle;" />, with <img src="https://math.vercel.app/?from=p" alt="p" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=q" alt="q" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=r" alt="r" style="display: inline; vertical-align: middle;" /> being the process_id for processes <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=Q" alt="Q" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=R" alt="R" style="display: inline; vertical-align: middle;" /> respectively. Note that the first event for both process <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" /> and <img src="https://math.vercel.app/?from=Q" alt="Q" style="display: inline; vertical-align: middle;" /> have first request event with timestamp 1. Since <img src="https://math.vercel.app/?from=p%20%26%23x3C%3B%20q" alt="p &amp;#x3C; q" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=(1%2Cp)%20%5Crightarrow%20(1%2Cq)" alt="(1,p) \rightarrow (1,q)" style="display: inline; vertical-align: middle;" />.</p>
<p>&#x3C;img style={{width: "100%", padding: "1.4em", maxWidth: 600, margin: "0 auto" }} src="/images/tc-po-example-all.svg" /></p>
<p>The same execution is show below with only a subset of events and messages highlighted, which are related to <img src="https://math.vercel.app/?from=(1%2Cp)" alt="(1,p)" style="display: inline; vertical-align: middle;" /> request.
&#x3C;img style={{width: "100%", padding: "1.4em", maxWidth: 600, margin: "0 auto" }} src="/images/tc-po-example-p.svg" /></p>
<p>Now, the same execution with subset of events and messages relevant for <img src="https://math.vercel.app/?from=(1%2Cq)" alt="(1,q)" style="display: inline; vertical-align: middle;" /> highlighted.
&#x3C;img style={{width: "100%", padding: "1.4em", maxWidth: 600, margin: "0 auto" }} src="/images/tc-po-example-q.svg" /></p>
<p>Notice how even though the requests are happening concurrently and process <img src="https://math.vercel.app/?from=R" alt="R" style="display: inline; vertical-align: middle;" /> received request from <img src="https://math.vercel.app/?from=Q" alt="Q" style="display: inline; vertical-align: middle;" />, before request from <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" /> completes it's mutually exclusive execution <img src="https://math.vercel.app/?from=Q" alt="Q" style="display: inline; vertical-align: middle;" />.</p>
<p>Implementing an arbitrary state machine should also be straight forward. E.g. mutual exclusion could be used to decide on which command is executed next, across the state machines. Hence implementing replicated state machine. Although, it could be made slightly faster by send acknowledgement to all process. See <a href="https://www.google.co.in/books/edition/_/z_m2DwAAQBAJ?hl=en&#x26;gbpv=1&#x26;pg=PA54&#x26;dq=lamport+clock+smr">Concurrency: The Works of Leslie Lamport</a></p>
<h3>Real world needs clocks</h3>
<p>Note also that the algorithm is distributed in the sense that state machine is only cares about sequence of events, not when it happens. But some events might have a happened-before relation in the physical world. E.g you transferring money to a friend and calling them to check it on their end.
&#x3C;img style={{width: "100%", padding: "1.4em", maxWidth: 600, margin: "0 auto" }}  src="/images/tc-po-external.png" /></p>
<p>Lamport points out that synched clocks could be used to preserve happened-before relations outside of the system. As an example, with the mutual exclusion algorithm above, the user commands could be run based on the total order (which uses synched clock for timestamps). This would mean, event <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" /> would be run by the state machine after event <img src="https://math.vercel.app/?from=c" alt="c" style="display: inline; vertical-align: middle;" /> since <img src="https://math.vercel.app/?from=c" alt="c" style="display: inline; vertical-align: middle;" />'s timestamp would be smaller than <img src="https://math.vercel.app/?from=b" alt="b" style="display: inline; vertical-align: middle;" />.</p>
<h2>Observations</h2>
<p>I like to think of TCO paper as a gateway drug to distributed systems. This section might feel a little contrived. But the associations help me think, so why not. I am just starting to explore these topics myself, slowly. So, read it with more skepticism. I will link a few resources which might help with exploring the topics.</p>
<ul>
<li><strong>Models of Distributed system</strong>: For thinking about distribute systems, it helps to understand the model on which the theory builds. E.g in this paper, the models used is asynchronous communication and no-failure. Asynchronous communication is realistic, but no-failure is not. Communication could be asynchronous, synchronous or semi-asynchronous. Failures can be fail-stop, crash, crash-recovery, Byzantine etc. Understanding the assumptions, helps create a mental model of what is applicable where. In particular, pay close attention to models used in impossibility (see FLP Impossibility below), or in proofs on consensus algorithms. See <a href="http://www.cs.yale.edu/homes/aspnes/classes/465/notes.pdf">these lecture notes</a> for some coverage on different models. Realistic model might be semi-asynchronous with crash-recovery.</li>
</ul>
<ul>
<li><a href="https://en.m.wikipedia.org/wiki/Logical_clock"><strong>Logical clock</strong></a>: the clock described in the paper is usually known as Lamport timestamps. More logical clocks have been formulated. E.g. vector clock, which helps detecting causal relations (Lamport clock only keeps the relation). Check out the <a href="https://en.m.wikipedia.org/wiki/Logical_clock">wiki on logical clocks</a>.</li>
<li><a href="https://en.wikipedia.org/wiki/Consensus_(computer_science)#The_FLP_impossibility_result_for_asynchronous_deterministic_consensus"><strong>FLP Impossibility</strong></a>: The model used in TCO paper assumes no-failure. What happens if failure is part of the model (e.g. more realistic systems)? Turns out, with asynchronous networks and crash fail, <strong>consensus can't be guaranteed</strong>. But this doesn't mean consensus can't be achieved. The proof for this seems interesting.</li>
<li><a href="https://en.wikipedia.org/wiki/Consensus_(computer_science)"><strong>Consensus</strong></a>: Consensus is an important part of distributed system. Although FLP impossibility means consensus can't be guaranteed, but I think the worst case happens only if there is an oracle which knows exactly when to slow down a process. Practically, consensus is used a lot, in fact in almost all distributed systems, consensus algorithms might be involved in one way or the other. In the original paxos paper, this is the synod algorithm.</li>
<li><a href="https://en.wikipedia.org/wiki/State_machine_replication"><strong>Replicated state machine</strong></a>: If you read papers on consensus, you will come across replicated state machines a lot. One could implement a deterministic state machine on a single machine. But to be reliable (in case of failure), data needs to be replicated to more than one machine. Naive implementation of this might lead to inconsistent data on different machines. To have consistent data with replication, consensus is needed (where a set of machines agree on what the current state of the system is). Most protocols like Paxos, Raft maintain a log and use consensus to append to it across the state machines. You could read <a href="https://escholarship.org/uc/item/9w79h2jg">A Generalized Multi-Leader State Machine Replication Tutorial</a>, which refers more papers on the topic.</li>
<li><a href="https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type"><strong>CRDT</strong></a>: Replicated state machines allow for generic fault tolerant systems. It does this by having consensus on append to a command log. But if the commands are commutative, those could be applied in any order. There is subset on optimizations on paxos for concurrent commutative commands, called <a href="https://en.wikipedia.org/wiki/Paxos_(computer_science)#Generalized_Paxos">Generalized Paxos</a>. In the extreme case, if all operations are commutative, then you have this nice situation where you don't need consensus. And replicas can converge on the same state, eventually. These data structures with commutative operations are called CRDT. &#x3C;>[video] Strong Eventual Consistency and Conflict-free Replicated Data Types&#x3C;/> -- Marc Shapiro</li>
<li><strong>Clocks</strong>: Even with no-fault assumption, TCO paper still points out that clocks are important, to capture the causal relations that are not part of the system. This is an important part of distributed system. Example, <a href="http://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf">Spanner</a> uses synchronized clocks to guarantee that even external causal relations are maintained.</li>
</ul>
<h2>More references</h2>
<ul>
<li><a href="https://youtu.be/SXt3-iZpQQc?t=4686">Oral History of Leslie Lamport - Part 1</a></li>
<li><a href="https://www.youtube.com/watch?v=BRvj8PykSc4">Keeping Time in Real Systems</a> by <em>Kavya Joshi</em></li>
<li><a href="https://www.youtube.com/playlist?list=PLeKd45zvjcDFUEv_ohr_HdUFe97RItdiB">Distributed Systems lecture series</a> by <em>Martin Kleppmann</em></li>
</ul>
<h2>Acknowledgement</h2>
<p>Thanks to <a href="https://akash-akya.github.io/">Akash</a>, <a href="https://rahulj.dev/">Rahul</a>, <a href="https://rohitshinde.in/">Rohit Shinde</a> and others for their feedback.</p>]]></content:encoded>
    </item>
    <item>
      <title>On Compound Interest</title>
      <description>Observations on exponential growth and its affects on investment returns.</description>
      <link>https://ciju.in/writings/compound-interest</link>
      <guid isPermaLink="true">https://ciju.in/writings/compound-interest</guid>
      <pubDate>Fri, 01 Sep 2017 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p><a href="https://en.wikipedia.org/wiki/Exponential_growth">Exponential growth</a> is unintuitive See: <a href="https://www.youtube.com/watch?v=O133ppiVnWY">Exponential Growth Arithmetic, Population and Energy (video)</a> talk by Al Bartlett. But thankfully, there are tricks which help in understanding implications of different rates of growth. The trick is finding doubling period, and number of doublings. If you are only interested in the trick, jump to <a href="#mental-math">Mental math</a>. Rest of the article goes through various properties of compounding curve by looking at the equation (and charts) behind itArticle is not a financial advice. Doesn't cover risk, real Interest rate, taxes, or other factors that affect investments. Rather, we will go through rough calculations with intent is to understand broad behavior, and not details.. It's simple observations, but I haven't found a similar coverage elsewhere. Article does assume familiarity with basic maths. Multiplication and equational reasoning should be enough to understand most of it.</p>
<h2>Motivation</h2>
<p>To motivate why you should care, here is a made up scenario. You want to invest  today and found two options both offering annual interest rate of 10% for 30 years. Your two options are, investment with annual interest paid back to you (I will call this dividend based investment in rest of the article), or compounding interest. Which one would you opt for? Here are the approximate returns to help you decide.</p>
<ul>
<li>Dividend: <strong>&#x3C;OverNote inlineContent={&#x3C;Currency amount={1000 + 100*30} />} overContent={} /></strong></li>
<li>Compounding: <strong>&#x3C;OverNote inlineContent={} overContent={ }/></strong></li>
</ul>
<p>Here is another hypothetical scenario. You have a friend same age as you. Your friend invested  at the age of 20. You being lazy, invested your first  at the age of 30 (10 years after your friend). Both investments compound at 10% annual interest rate. How much would your respective investments grow to, when you both are 60 years old?</p>
<ul>
<li>your friend: &#x3C;OverNote inlineContent={} overContent={ } /></li>
<li>you: &#x3C;OverNote inlineContent={} overContent={ } /></li>
</ul>
<p>If you delayed your investment by another 5 years (invested at age 35), the return would have been even lower: &#x3C;OverNote inlineContent={} overContent={ } /> .</p>
<p>Compounding is unintuitive but has real and significant implications. We will explore some of it's characteristics in this article.</p>
<hr>
<ul>
<li></li>
<li>Hovering over charts shows some details.</li>
<li>Text styled like  would show some details on hover (click on mobile/tablet).</li>
</ul>
<h2>Summary</h2>
<p>Some financial wisdom, which are based on the compound interest equation:</p>
<ul>
<li>Compounding is exponential process.
<ul>
<li>Time matters. <strong>Invest early</strong>If you start investing at the age of 20, and don't touch the money till 60, you can utilize 40 years of compounding. Later you start, less years for compounding..</li>
<li>Every percent in interest rate matters.</li>
</ul>
</li>
<li>Splitting investment, other things being same, doesn't affect return. A good way to manage risk.</li>
</ul>
<h3>Mental math</h3>
<p>If you like doing <a href="https://en.wikipedia.org/wiki/Back-of-the-envelope_calculation">back-of-the-envelope</a> calculations, you might find these tricks useful.</p>
<ul>
<li><strong>Rule of 72</strong>: <img src="https://math.vercel.app/?from=72%2Fr" alt="72/r" style="display: inline; vertical-align: middle;" /> is an approximation on the doubling period of an investment. But this doesn't give you an idea of time value of the investment.</li>
<li><strong>Doublings</strong>: Each doubling period, money doubles. <img src="https://math.vercel.app/?from=%5Cfrac%7Binvestment%5C%20period%7D%7Bdoubling%5C%20period%7D" alt="\frac{investment\ period}{doubling\ period}" style="display: inline; vertical-align: middle;" /> would give you doublings. And <img src="https://math.vercel.app/?from=2%5E%7Bdoublings%7D" alt="2^{doublings}" style="display: inline; vertical-align: middle;" /> would roughly give the multiple by which the investment would grow. This is simpler to calculate if <img src="https://math.vercel.app/?from=investment%5C%20period" alt="investment\ period" style="display: inline; vertical-align: middle;" /> is a multiple of <img src="https://math.vercel.app/?from=doubling%5C%20period" alt="doubling\ period" style="display: inline; vertical-align: middle;" />. Few examples of back-of-envelope approximations:
<ul>
<li>10% investment over 35 years. Doubling period is &#x3C;OverNote inlineContent="7 years" overContent={ } />. Number of doublings, &#x3C;OverNote inlineContent={5} overContent={ } />. Investment grows by &#x3C;OverNote inlineContent={Math.pow(2, 5)} overContent={ } />.</li>
<li>7% has doubling period of 10 years. In 30 years, the investment should grow &#x3C;OverNote inlineContent={Math.pow(2, 30/10)} overContent={    } /> times. In 40 years, investment should grow &#x3C;OverNote inlineContent={Math.pow(2, 40/10)} overContent={    } /> times.</li>
</ul>
</li>
</ul>
<h2>Characteristics of compounding investments</h2>
<p>Now to the main content. We will start with what compounding and dividend based investment mean in this article. Then look at the equation and curves etc.</p>
<h3>Compounding and dividend</h3>
<p>Dividend based investment, in this article, is used for investments where the interest doesn't get reinvested. You invest , but each year, take out the interest.</p>
<p>By the end of two years, you would have  +  + , or </p>
<p>In case of compound interest approach, interest made is put back into investment (or is not taken out of the investment).</p>
<p>In this case, by end of 2nd year, you would have  +  + , or . The difference at 2 years is small. But with time, compounding would return significantly more.</p>
<p>You can learn more about compound interest at <a href="https://www.khanacademy.org/economics-finance-domain/core-finance/interest-tutorial#compound-interest-tutorial">Khan Academy</a>.</p>
<h3>Equation</h3>
<p>Let's first understand the equation for compounding. To understand the equation, let's say you invest , with an interest rate of 10%. We will use &#x3C;OverNote inlineContent={} overContent={10% interest would mean  is 0.10} />  for rate of interest, <img src="https://math.vercel.app/?from=n" alt="n" style="display: inline; vertical-align: middle;" /> for the number of years, <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" /> for the initial amount and <img src="https://math.vercel.app/?from=P'" alt="P&apos;" style="display: inline; vertical-align: middle;" /> for amount at the end of year <img src="https://math.vercel.app/?from=n" alt="n" style="display: inline; vertical-align: middle;" />. Every year, you get interest on money that was there at the starting of the year. E.g.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cbegin%7Balign%7D%0A%26%23x26%3Bmoney%5C%20at%5C%20year%5C%20end%5C%20%5C%5C%26%23x26%3B%20%3D%5C%20money%5C%20at%5C%20year%5C%20start%5C%20%2B%20%5C%5C%26%23x26%3B%5C%20%5C%20(%20money%5C%20at%5C%20year%5C%20start%5C%20*%5C%20rate%5C%20of%5C%20interest%20)%5C%5C%0A%5Cend%7Balign%7D" alt="\begin{align}
&amp;#x26;money\ at\ year\ end\ \\&amp;#x26; =\ money\ at\ year\ start\ + \\&amp;#x26;\ \ ( money\ at\ year\ start\ *\ rate\ of\ interest )\\
\end{align}" /></div>
<p>For the first year:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cbegin%7Balign%7D%0A%7B1%5E%7Bst%7D%5C%20year%7D%20%26%23x26%3B%3D%20100%20%2B%20100*0.10%20%5C%5C%0A%20%26%23x26%3B%3D%20100%20*%20(1%20%2B%200.10)%20%5C%5C%0A%20%26%23x26%3B%3D%20P%20*%20(1%20%2B%20r)%20%5C%5C%0A%5Cend%7Balign%7D" alt="\begin{align}
{1^{st}\ year} &amp;#x26;= 100 + 100*0.10 \\
 &amp;#x26;= 100 * (1 + 0.10) \\
 &amp;#x26;= P * (1 + r) \\
\end{align}" /></div>
<p>For the second year:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cbegin%7Balign%7D%0A%7B2%5E%7Bnd%7D%5C%20year%7D%20%26%23x26%3B%3D%20%7B1%5E%7Bst%7D%5C%20year%7D%20%2B%20%7B1%5E%7Bst%7D%5C%20year%7D*0.10%20%5C%5C%0A%26%23x26%3B%3D%20%7B1%5E%7Bst%7D%5C%20year%7D%20*%20(1%20%2B%200.10)%20%5C%5C%0A%26%23x26%3B%3D%20100%20*%20(1%20%2B%200.10)%20*%20(1%20%2B%200.10)%20%5C%5C%0A%26%23x26%3B%3D%20100%20*%20(1%20%2B%200.10)%5E2%20%5C%5C%0A%26%23x26%3B%3D%20P%20*%20(1%20%2B%20r)%5E2%20%5C%5C%0A%5Cend%7Balign%7D" alt="\begin{align}
{2^{nd}\ year} &amp;#x26;= {1^{st}\ year} + {1^{st}\ year}*0.10 \\
&amp;#x26;= {1^{st}\ year} * (1 + 0.10) \\
&amp;#x26;= 100 * (1 + 0.10) * (1 + 0.10) \\
&amp;#x26;= 100 * (1 + 0.10)^2 \\
&amp;#x26;= P * (1 + r)^2 \\
\end{align}" /></div>
<p>And so on. If you invest amount <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" /> with an annually compounded interest <img src="https://math.vercel.app/?from=r" alt="r" style="display: inline; vertical-align: middle;" />, in <img src="https://math.vercel.app/?from=n" alt="n" style="display: inline; vertical-align: middle;" /> years the total amount <img src="https://math.vercel.app/?from=P'" alt="P&apos;" style="display: inline; vertical-align: middle;" /> would be:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=P'%20%3D%20%7B%20P(1%20%2B%20r)%5En%20%7D" alt="P&apos; = { P(1 + r)^n }" /></div>
<p>For dividend based investments, the equation would be:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=D'%20%3D%20D(1%20%2B%20r*n)" alt="D&apos; = D(1 + r*n)" /></div>
<h3>Multiple</h3>
<p>First thing to note is that the return <img src="https://math.vercel.app/?from=P'" alt="P&apos;" style="display: inline; vertical-align: middle;" /> is a multiple of initial investment <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" />. All the observations in the article depend on this property. In other words, we can write the equation as:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cfrac%7BP'%7D%7BP%7D%20%3D%20%7B%20(1%20%2B%20r)%5En%20%7D" alt="\frac{P&apos;}{P} = { (1 + r)^n }" /></div>
<p>This means, In terms of growth rate, it doesn't matter whether you invest  or . They both grow in the same way. What matters is the interest rate. E.g. if the interest rate is 7%, in the first year both of them would grow to 1.07 times the initial value. In the second year, both of them would be approximate &#x3C;OverNote inlineContent={1.14} overContent={ } /> . In the third year, both of them would be approximate &#x3C;OverNote inlineContent={1.23} overContent={ } /> times the initial value. <strong>So, for the same interest rate, the more money you put in, the more returns you get</strong>.</p>
<p>Another nice property is thatGiven interest rate and duration is same. you can split the money into multiple investments and get the same returns . Ex, you could replace <img src="https://math.vercel.app/?from=P" alt="P" style="display: inline; vertical-align: middle;" /> with <img src="https://math.vercel.app/?from=P_1%20%2B%20P_2%20%2B%20...%20%2B%20P_n" alt="P_1 + P_2 + ... + P_n" style="display: inline; vertical-align: middle;" /></p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=P'%20%3D%20(P_1%20%2B%20P_2%20%2B%20...%20%2B%20P_n)%7B%20(1%20%2B%20r)%5En%20%7D" alt="P&apos; = (P_1 + P_2 + ... + P_n){ (1 + r)^n }" /></div>
<p>This is a good way to manage risk. High interest usually comes with high risk. Putting all the money in a single investment would mean loosing all the money if the fund goes down. Instead, the money could be invested in multiple funds.</p>
<p>The multiple property is applicable for dividend based investments also. E.g.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cfrac%7BD'%7D%7BD%7D%20%3D%20(1%20%2B%20r*n)" alt="\frac{D&apos;}{D} = (1 + r*n)" /></div>
<h3>Rule of 72</h3>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=doubling%5C%20period%20%3D%20%7B%2072%20%5Cover%20interest%5C%20rate%20%7D" alt="doubling\ period = { 72 \over interest\ rate }" /></div>
<p>This is a way to approximate the doubling time of investment.</p>
<p>Again (I find it interesting and worth repeating): <em><strong>doubling period doesn't depend on how much money you put in</strong></em>. Put as much as you can, you will get double of it, after a doubling period.</p>
<h3>Doubling continues</h3>
<p>The Rule of 72 gives us a number to compare. It's one doubling time. An important but unintuitive number. With every doubling time, your investment doubles. After <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" /> doubling periods the investment would be <img src="https://math.vercel.app/?from=2%5E%7Bdoubling%5C%20period%7D" alt="2^{doubling\ period}" style="display: inline; vertical-align: middle;" /> times it's original amount. E.g. doubling time of  and  don't seem too far apart. But in 12 years, doubling time of 1 year would return &#x3C;OverNote inlineContent={4096} overContent={ } /> times the original amount. While doubling time of 4 years would return &#x3C;OverNote inlineContent={8} overContent={} /> times the original amount.</p>
<p>Dividend based investment doubles in <img src="https://math.vercel.app/?from=%5Cfrac%7B100%7D%7Br%7D" alt="\frac{100}{r}" style="display: inline; vertical-align: middle;" /> yearsPlay with <img src="https://math.vercel.app/?from=D'%20%3D%20D(%201%20%2B%20r%20*%20n)" alt="D&apos; = D( 1 + r * n)" style="display: inline; vertical-align: middle;" /> to reason why.. Although it is larger than in case of compounding based investment, but the real difference comes because of continued doubling. Next doubling in dividend happens in <img src="https://math.vercel.app/?from=%5Cfrac%7B300%7D%7Br%7D" alt="\frac{300}{r}" style="display: inline; vertical-align: middle;" />. And this keeps increasing for future doublings. For compounding, doubling period remains same. And after <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" /> doubling periods, investment would return <img src="https://math.vercel.app/?from=2%5E%7Bx%7D" alt="2^{x}" style="display: inline; vertical-align: middle;" /> times initial investment. That is the significant difference.</p>
<h3>Value of 1%</h3>
<p>What difference does a 1% change in interest rate make? Hover over the plot below to see the doubling time for the interest rate.</p>
<p>Notice how when interest rates are low, 1% makes a big difference in doubling period. This was a surprise to me. Although this does mean that 1% matters more for returns, when interest rate is low. Every 1% matters, no matter what interest rate you are getting :)</p>
<h3>Value of interest rate</h3>
<p>The chart below shows return curves for different interest rates. The higher the interest rate, the steeper the curve.</p>
<h3>Value of time</h3>
<p>Each of the curves below represents a time period (ex: 40, 30, 20 years). The x-axis is the interest rate, and y is the multiple of the investment. Again, the longer you let your investment grow, the bigger the returns. Note how fast the curve grows for high-interest rates and long periods.</p>
<p>With an interest rate of 12%, after 40 years, your investment would have grown 100 times!</p>
<h3>In one table</h3>
<p>Here is a table of interest rates, years and returns (as multiple of initial amount) associated with that. The top right cell represents 25% annual interest compounded for 35 years. Initial amount would grow 2500 times. Let's say you invested . That would become <strong></strong>.</p>
<h2>Value of maths?</h2>
<p>Much of what we figured out, is just maths and looking at curves. Let's play around with it a little more.</p>
<h3>Where does 72 come from?</h3>
<p>We will attempt a close enough answer. Let's look at our equation again.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%5Cfrac%7BP'%7D%7BP%7D%20%3D%20%7B%20(1%20%2B%20r)%5En%20%7D" alt="\frac{P&apos;}{P} = { (1 + r)^n }" /></div>
<p>Doubling means <img src="https://math.vercel.app/?from=P'%20%3D%202*P" alt="P&apos; = 2*P" style="display: inline; vertical-align: middle;" />, or <img src="https://math.vercel.app/?from=%5Cfrac%7BP'%7D%7BP%7D%20%3D%202" alt="\frac{P&apos;}{P} = 2" style="display: inline; vertical-align: middle;" />. In other we need to solve for:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=2%20%3D%20%7B%20(1%20%2B%20r)%5En%20%7D" alt="2 = { (1 + r)^n }" /></div>
<p>Taking natural log on both sides.</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=ln(2)%20%3D%20%7B%20n%20*%20ln(1%20%2B%20r)%20%7D" alt="ln(2) = { n * ln(1 + r) }" /></div>
<p>Or</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=n%20%3D%20%7B%20ln(2)%20%5Cover%20ln(1%20%2B%20r)%20%7D" alt="n = { ln(2) \over ln(1 + r) }" /></div>
<p>Now here is a nice trick. Turns out, for small values of <img src="https://math.vercel.app/?from=r" alt="r" style="display: inline; vertical-align: middle;" />, <img src="https://math.vercel.app/?from=ln(1%20%2B%20r)" alt="ln(1 + r)" style="display: inline; vertical-align: middle;" /> is approximately <img src="https://math.vercel.app/?from=r" alt="r" style="display: inline; vertical-align: middle;" />. Ex, <img src="https://math.vercel.app/?from=ln(1.01)" alt="ln(1.01)" style="display: inline; vertical-align: middle;" /> it's 0.01, for <img src="https://math.vercel.app/?from=ln(1.2)" alt="ln(1.2)" style="display: inline; vertical-align: middle;" /> it's 0.18, approximately. So, for most practical interest rates, we could just use:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=n%20%3D%20%7B%20ln(2)%20%5Cover%20r%20%7D" alt="n = { ln(2) \over r }" /></div>
<p><img src="https://math.vercel.app/?from=ln(2)" alt="ln(2)" style="display: inline; vertical-align: middle;" /> turns out to be 69, so doubling time could be equated to (approximately)</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=n%20%3D%20%7B%2069%20%5Cover%20r%20%7D" alt="n = { 69 \over r }" /></div>
<p>But we have been using 72! <a href="https://en.wikipedia.org/wiki/Rule_of_72#Choice_of_rule">Wiki explains</a> the reasons behind choosing 72 (or 70 or 69).</p>
<h3>Slopes</h3>
<p>Let's again start with the compound interest equation <img src="https://math.vercel.app/?from=(1%20%2B%20r)%5En" alt="(1 + r)^n" style="display: inline; vertical-align: middle;" />. For a curve, the slope at a point is one way of figuring out how fast change is happening at that certain point. A point in the curve represents some point in time and the <em>change in return</em> at that time. With the slope of the curve, if we assume it to be the same for a year around the point, we can approximate the rate of return in that year, by calculating the change in return.</p>
<p>Derivative gives us the slope curve. Derivative of the compound interest equation:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%7B%20%5Cfrac%7Bd(1%20%2B%20r)%5En%7D%7Bdn%7D%20%7D%20%3D%20%7B%20ln(1%20%2B%20r)(1%20%2B%20r)%5En%20%7D" alt="{ \frac{d(1 + r)^n}{dn} } = { ln(1 + r)(1 + r)^n }" /></div>
<p>We learned earlier that for small values of r, <img src="https://math.vercel.app/?from=ln(1%2Br)" alt="ln(1+r)" style="display: inline; vertical-align: middle;" /> could be replaced with <img src="https://math.vercel.app/?from=r" alt="r" style="display: inline; vertical-align: middle;" />. So, we could write the above equations as:</p>
<div style="text-align: center; margin: 1em 0;"><img src="https://math.vercel.app/?from=%7B%20r(1%20%2B%20r)%5En%20%7D" alt="{ r(1 + r)^n }" /></div>
<p>Now, let's consider what this means.</p>
<h2>Some thoughts around exponentials</h2>
<p>It's relatively easy for our brains to think of linear processes. E.g. what would be your age in 10 years?current_age + 10 Or you get  every year as dividend on your investment, how much dividend would you get in total, after 10 years? Exponential processes (like compounding) on the other hand, are not as intuitive, but could have a much bigger impact on our life.</p>
<p><a href="https://en.wikipedia.org/wiki/Exponential_growth">Exponential growth</a> is a process where the growth in quantity is proportional to its current value. E.g. when we say the population is growing 2% every year, we mean the population grows by 2% of what it was, at the starting of that year. <a href="https://www.cebm.net/covid-19/exponential-growth-what-it-is-why-it-matters-and-how-to-spot-it/">Covid-19 growth</a> is proportional to the affected people, given enough population and no preventive measures. Knowledge grows exponentially. If you improve on something by 1% every day, by end of the year, you would be about 36Try doing back-of-the-envelope to arrive at <strong>greater than 32 times</strong>? Close enough to prove the point. times better than when you started.</p>
<h2>What now?</h2>
<p>There are many factors to consider for personal finance and investment. Mostly they come down to risk and return (which includes the interest rate, taxes, management fees, entry and exit fees, etc). Personal finance is a big topic. You could probably start by reading discussions at <a href="https://www.reddit.com/r/personalfinance/">Personalfinance subreddit</a>. But remember, <strong>to get the most out of compounding, invest early</strong>.</p>
<p>Also, it's interesting to note that throughout the article, all we did was look at the implications of the equation <img src="https://math.vercel.app/?from=P'%20%3D%20P(1%20%2B%20r)%5En" alt="P&apos; = P(1 + r)^n" style="display: inline; vertical-align: middle;" />.</p>
<h2>Pointers to explore more</h2>
<ul>
<li><a href="https://en.m.wikipedia.org/wiki/Time_value_of_money">Time value of money</a></li>
<li><a href="https://en.wikipedia.org/wiki/Rule_of_72">Rule of 72</a></li>
<li><a href="https://www.youtube.com/watch?v=O133ppiVnWY">Exponential Growth Arithmetic, Population and Energy (video)</a> talk by Al Bartlett</li>
<li><a href="https://www.amazon.in/Functions-Graphs-Dover-Books-Mathematics-ebook/dp/B00BLRDHC4">Functions and Graphs</a> by I. M. Gelfand, E. G. Glagoleva, E. E. Shnol.
A nice book on properties of functions and graphing them.</li>
<li>Tools
<ul>
<li><a href="https://www.desmos.com/">Desmos - A tool to chart equations.</a></li>
<li><a href="https://www.geogebra.org/calculator">GeoGebra</a></li>
<li>If you are on macOS, Grapher.app is also good.</li>
</ul>
</li>
</ul>
<h2>Acknowledgment</h2>
<p>Thanks to <a href="https://saneef.com/">Saneef</a>, <a href="https://rahulj.dev/">Rahul</a>, <a href="https://ananthakumaran.in/">Anantha Kumaran</a>, <a href="https://rohitshinde.in/">Rohit Shinde</a> and many others for their feedback.</p>]]></content:encoded>
    </item>
    <item>
      <title>Y combinator in small steps</title>
      <description>Representing recursion without a named function, in JavaScript</description>
      <link>https://ciju.in/writings/2015-07-16-y-combinator-in-small-steps</link>
      <guid isPermaLink="true">https://ciju.in/writings/2015-07-16-y-combinator-in-small-steps</guid>
      <pubDate>Thu, 16 Jul 2015 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>The Y combinator is an interesting construct, allowing recursion without referring the function being recursed. In other words, call a function recursively, without naming it. We will go through one approach of deriving it.</p>
<p>This approach mostly follows <a href="http://www.dreamsongs.com/NewFiles/WhyOfY.pdf">WhyOfY</a> by Richard P GabrielA somewhat similar approach is followed by James Coglan's <a href="https://blog.jcoglan.com/2008/01/10/deriving-the-y-combinator/">blog post.</a>. And watch an interesting <a href="https://www.youtube.com/watch?v=FITJMJjASUs">talk</a> on it, by Jim Weirich.. We will derive it in JavaScript, in steps. Each step is complete. Click on the 'Edit in JSFiddle' to explore the steps.</p>
<h2>Premise &#x26; setup</h2>
<p>Lets pick a simple example, so we can concentrate on exploring recursion. Given a number, n, return the sum of numbers from 1 to n. To start with, below is a recursive solution for the problem. Individual steps are hosted in JSFiddle, for you to play around.</p>
<pre><code class="language-js">var sum = function (n) {
    return n === 1 ? 1 : n + sum(n - 1);
};
console.assert(sum(5) === 15, sum(5));
</code></pre>
<p><em><a href="http://jsfiddle.net/ciju/rLd57d07/12/">try in fiddle</a></em></p>
<h2>The process</h2>
<p>We have to remove the reference to sum, inside the function, which
fortunately leads to the Y combinator. One approach to calling a
function, without using its name, is to pass the function as
parameter.</p>
<pre><code class="language-js">var s1 = function (f, n) {
    return n === 1 ? 1 : n + f(f, n - 1);
}
console.assert(s1(s1, 5) === 15);
</code></pre>
<p><em><a href="//jsfiddle.net/ciju/rLd57d07/13/">try in fiddle</a></em></p>
<p>We have just moved the function name (reference) from inside the
function, to the function call. As a next step, we could pass the
function as a <a href="https://en.wikipedia.org/wiki/Currying">curried param</a>.</p>
<p>This helps later, in abstracting the passing of function as
parameter, out of the logic for the problem.</p>
<pre><code class="language-js">var s2 = function (h) {
    return function (n) { // inner function
        return n === 1 ? 1 : n + h(h)(n - 1);
    };
};
console.assert(s2(s2)(5) === 15);
</code></pre>
<p><em><a href="//jsfiddle.net/ciju/rLd57d07/25/">try in fiddle</a></em></p>
<p>The double call inside the inner function, is quite irrelevant to the
problem of calculating sum. The logic of sum shouldn't know that
h(h) gives the next function call. The recursive function should
just receive a function, to continue the recursion with. We could
abstract that in another function. Ex:</p>
<pre><code class="language-js">// replace
return function (n) {
    return n === 1 ? 1 : n + h(h)(n-1);
};

// with
return (function(f) {
    return function (n) {
        return n === 1 ? 1 : n + f(n-1);
    };
})(function (n) {
    return h(h)(n);
});
</code></pre>
<p>Why not pass h(h) as parameter? Why do we have to wrap it in a
function?</p>
<p>Here is the complete version.</p>
<pre><code class="language-js">var s3 = function (h) {
    return (function (f) { // sum function
        return function (n) {
            return n === 1 ? 1 : n + f(n - 1);
        };
    })(function (n) {
        return h(h)(n);
    });
}
console.assert(s3(s3)(5) === 15, s3(s3)(5));
</code></pre>
<p><em><a href="//jsfiddle.net/ciju/rLd57d07/20/">try in fiddle</a></em></p>
<p>In the current version, the function dealing with the sum logic,
doesn't have any dependency on context, or specific knowledge about
how to get the next function. Lets name it as sum (for the time
being). Ex.</p>
<pre><code class="language-js">var sum = function(f) {
    return function (n) {
        return n === 1 ? 1 : n + f(n-1);
    };
};
</code></pre>
<p>This is just so we can see the real changes in code. Here is the
recursion with sum.</p>
<pre><code class="language-js">var sum = function (f) {
    return function (n) {
        return n === 1 ? 1 : n + f(n - 1);
    };
};

var s4 = function (h) {
    return sum(function (n) {
        return h(h)(n);
    });
};
console.assert(s4(s4)(5) === 15);
</code></pre>
<p><em><a href="//jsfiddle.net/ciju/rLd57d07/16/">try in fiddle</a></em></p>
<p>To evaluate the recursion, we had to call s4 with itself, ex
s4(s4). To not use a name, we would have to abstract it in a
function. We can define a function which s4 as parameter, and call
it with itself as parameter.</p>
<pre><code class="language-js">var s5 = (function (f) {
    return f(f);
})(s4);
console.assert(s5(5) === 15);
</code></pre>
<p>Expanding the definition of s4 gives.</p>
<pre><code class="language-js">var sum = function (f) {
    return function (n) {
        return n === 1 ? 1 : n + f(n - 1);
    };
};

var s5 = (function (g) {
    return g(g);
})(function (h) {
    return sum(function (n) {
        return h(h)(n);
    });
});
console.assert(s5(5) === 15);
</code></pre>
<p><em><a href="//jsfiddle.net/ciju/rLd57d07/21/">try in fiddle</a></em></p>
<p>We are almost done. Now, we just need to pass the actual function (ex sum in our case) as a parameter. Here is the Y combinator.</p>
<pre><code class="language-js">var Y = function (fn) {
    return (function (g) {
        return g(g);
    })(function (h) {
        return fn(function (n) {
            return h(h)(n);
        });
    });
};
var sum = function (f) {
    return function (n) {
        return n === 1 ? 1 : n + f(n - 1);
    };
};
console.assert(Y(sum)(5) === 15);
</code></pre>
<p><em><a href="//jsfiddle.net/ciju/rLd57d07/18/">try in fiddle</a></em></p>
<p>Or in its inlined form:</p>
<pre><code class="language-js">((function (fn) {
    return (function (g) {
        return g(g);
    })(function (h) {
        return fn(function (n) {
            return h(h)(n);
        });
    });
})(function (f) {
    return function (n) {
        return n === 1 ? 1 : n + f(n - 1);
    };
}))(5); // => 15
</code></pre>
<p><a href="//jsfiddle.net/ciju/rLd57d07/22/"><em>try in fiddle</em></a></p>
<h2>Explorations</h2>
<p>If you would like to think more about this, here are a few thoughts to
explore.</p>
<ol>
<li>
<p>We have only explored function with single argument. How could we make this work with multiple arguments.</p>
</li>
<li>
<p>Could we come up with a combinator, which doesn't take curried version of sum. Ex a combinator which takes sum defined as function sum(f, n) { return n + f(n-1); } as argument.</p>
</li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>Minimal Mochajs testing framework DSL</title>
      <description>A minimal mochajs testing framework DSL, in less than 100 lines of JavaScript.</description>
      <link>https://ciju.in/writings/2014-03-30-mocha-like-dsl-in-100-lines</link>
      <guid isPermaLink="true">https://ciju.in/writings/2014-03-30-mocha-like-dsl-in-100-lines</guid>
      <pubDate>Sun, 30 Mar 2014 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>Often, implementing essence of an idea helps a lot with understanding it. This is an attempt at understanding <a href="https://mochajs.org/">mocha</a> like DSL. Code at <a href="http://github.com/ciju/mini-mocha">github</a></p>
<h3>DSL details</h3>
<p>Lets define a Mocha TDD like DSL, with 4 commands.</p>
<pre><code class="language-js">describe(desc, fn)
setup(fn)
teardown(fn)
it(desc, fn)

// `describe` could be nested within `describe`, to arbitrary depth. ex:

describe('top level describe', function (){
    // ...
    describe('nested describe', function () {
        // ...
        describe('nested nested describe', function () {
            // ...
        })
        // ...
    });
    // ...
});
</code></pre>
<p>Each describe could have setup, teardown, it and well describe calls.</p>
<p>All functions registered to setup should be run first. Then all the
tests registered with it, and then all the nested describe have to
be executed. After all that, function registed to teardown should be
executed. Ex:</p>
<ul>
<li>Setup</li>
<li>Execute all the test in the level</li>
<li>Execute all nested levels</li>
<li>Teardown</li>
</ul>
<h3>So, how do we solve it.</h3>
<p>Lets first think just one level (ex: ignore nested describes). We
would have to collect all the DSL commands at that level, and then
execute them in a specific order. Note that we can't just execute the
commands in the order we come accros. Example, a setup might come
after tests (it). But all the setup in a level have to be run
before the tests. The way I acheive this is to define all the DSL
commands as functions which save the command, and its arguments, to be
executed later. ex: setup(fn) would save a pair ["setup", fn]. ex:</p>
<pre><code class="language-js">// 'key' being the dsl command, and 'val' arguments
function spush(key, val){
    stack[stack.length-1][key].push(val);
}
</code></pre>
<p>We will come to the stack part later. Now, once all the commands in
a describe level are collected, they are to be executed one by one.
Execution of setup and teardown commands is simple. Just execute
the function registered with them, in the context (there is a single
context, on which all setup and teardown work). Test (functions
registered with it) are executed by running the registered function,
and showing success or failure based on output. For now, it just
checks for the exception thrown by the function. Ex:</p>
<pre><code class="language-js">function reportTests(fn, desc) {
    desc = test_title(stack, desc);
    try {
        fn.call(ctx);
        success(desc);
    } catch(e) {
        failure(desc, e.message);
    }
}
</code></pre>
<p>Describe is the special case. Executing it, essentially means doing
the above, at the nested level (ex: the function registered with the
describe). Note that teardown should run at the end. So, some
information about the current level has to be saved, till all the
nested levels are done. This is the reason to have stack, to keep the
commands. describe is kinda the main function of the DSL.</p>
<pre><code class="language-js">function exec_describe(title, tfn) {
    stack.push(new_top(title));
    // collect 'describe', 'setup', 'teardown' and 'it' for the
    // current level
    tfn.call(ctx);
    exec_top();  // execute them
    stack.pop();
}
</code></pre>
<p>Well, thats mostly it. There are some small details. Like directly
executing the describe the first time we come across it (the process
has to start somewhere). Or printing the titles etc.</p>
<p>Full code below.</p>
<pre><code class="language-js">const success = desc => console.log(`${desc} : Pass`);
const failure = (desc, msg) => console.log(`:( ${desc} : Fail => ${msg}`);
const log = desc => console.log(desc);

const activity = {};
const stack = [];
const isEmptyStack = () => stack.length === 0;
const stackTop = () => stack[stack.length - 1];
const ctx = {};

const spush = (key, val) => stackTop()[key].push(val);

const indentedTitle = ctxt =>
  `${stack.map(() => '   ').join('')}${ctxt}`;

const newTop = title =>
  ({ title, tests: [], setup: [], teardown: [], testSuites: [] });

const execTop = () => 'setup tests testSuites teardown'.split(' ')
  .forEach(key => stackTop()[key].forEach(activity[key]));

const execTestSuite = (title, testSuiteFn) => {
  log(indentedTitle(title));
  stack.push(newTop(title));
  testSuiteFn.call(ctx);   // collect testSuites, setup, teardown and it.
  execTop();               // execute them
  stack.pop();
};

const reportTests = (fn, title) => {
  const desc = indentedTitle(title);

  try {
    fn.call(ctx);
    success(desc);
  } catch (e) {
    failure(desc, e.message);
  }
};

activity.setup = fn => fn.call(ctx);
activity.teardown = fn => fn.call(ctx);
activity.testSuites = ([title, testFn]) =>
  execTestSuite(title, testFn);
activity.tests = ([title, testFn]) =>
  reportTests(testFn, title);

export const test = (desc, fn) => spush('tests', [desc, fn]);
export const testSuite = (title, testfn) => {
  if (isEmptyStack()) {
    execTestSuite(title, testfn);
    return;
  }

  spush('testSuites', [title, testfn]);
};
export const setup = spush.bind(null, 'setup');
export const teardown = spush.bind(null, 'teardown');
</code></pre>
<p>Its nice to find out that an expressive DSL could be implemented (to
atleast experiment) in less than 100 lines of code.</p>]]></content:encoded>
    </item>
    <item>
      <title>Summarize Rails MySQL Database Tables</title>
      <description>Summarize Rails MySQL Database Tables</description>
      <link>https://ciju.in/writings/2013-09-07-overview-of-sql-tables</link>
      <guid isPermaLink="true">https://ciju.in/writings/2013-09-07-overview-of-sql-tables</guid>
      <pubDate>Sat, 07 Sep 2013 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>Because of how <a href="https://en.wikipedia.org/wiki/Ruby_on_Rails">ROR</a> manages/abstracts database, looking at the database tables, can give quite some information about the application. For an app that I had came across, I started with select count(*) from &#x3C;tbl1>; followed by a select * from &#x3C;tbl1> limit 10; for the tables in the database, one by one. But then I would look at a reference like account_id and would try to recollect what accounts table looked like. I would rather have liked to get the above summary for all the tables, copy them to a text editor and then rearrange and analyze them.</p>
<p>The script below defines procedure showalltbl to get above mentioned
summary for all the tables, that are passed as comma separated list to
itCould have achieved the same result in Ruby. But well..</p>
<pre><code class="language-sql">-- ref: http://stackoverflow.com/questions/7737970/procedure-to-loop-through-comma-separated-string-is-not-working
-- ref: http://www.java2s.com/Code/SQL/Procedure-Function/EXECUTEdynamicSQLcommand.htm

delimiter $

drop procedure if exists execsql$
create procedure execsql(q varchar(1000))
begin
      set @q = q;
      prepare stmt from @q;
      execute stmt;
      deallocate prepare stmt;
end$

drop procedure if exists showtbl$
create procedure showtbl(tbl varchar(100))
begin
      call execsql(concat("select \"", tbl, "\""));
      call execsql(concat("select count(*) as entries from ", tbl));
      call execsql(concat("select * from ", tbl, " limit 10"));
end$

drop procedure if exists showalltbl$
create procedure showalltbl(strids varchar(1000))
begin
  declare strlen    int default 0;
  declare substrlen int default 0;
  declare tbl varchar(100) default "";

  if strids is null then
    set strids = '';
  end if;

do_this:
  loop
    set strlen = char_length(strids);

    set tbl = substring_index(strids, ',', 1);
    call showtbl(tbl);
    set substrlen = char_length(tbl)+2;
    set strids = mid(strids, substrlen, strlen);

    if strids = null then
      leave do_this;
    end if;
    if strids = '' then
      leave do_this;
    end if;
  end loop do_this;

end$

delimiter ;
</code></pre>
<h2>How does this work?</h2>
<p>There are three functions defined in the script. The most basic being execsql. Let me start there. Its job is to take a string, and execute it as an SQL statement.</p>
<p>Next up is showtbl. It takes a table name as string. Uses execsql to select that string (so, the output shows the table name, to understand which table rest of the summary belongs to). Selects count on the table. And the show 10 entries from the table.</p>
<p>The last one is showalltbl, which takes the comma separate string of tables. Splits them and calls showtbl on them.</p>]]></content:encoded>
    </item>
    <item>
      <title>Gotunnel: make localhost server accessible over internet</title>
      <description>Gotunnel allows you to share server running on localhost, over the net. Supports http, https and websocket.</description>
      <link>https://ciju.in/writings/2013-03-26-gotunnel-make-localhost-server-accessible-over-internet</link>
      <guid isPermaLink="true">https://ciju.in/writings/2013-03-26-gotunnel-make-localhost-server-accessible-over-internet</guid>
      <pubDate>Tue, 26 Mar 2013 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>To access a server on the internet, you need its IP address and port. Your local machine might be running behind a <a href="http://en.wikipedia.org/wiki/Network_address_translation">NAT</a>. So, a server running on your local machine, might not be addressable from internet (ex: no publically visible IP). This is where localtunnelThere are many options also, like <a href="https://tunnlr.com/">tunnlr</a>, <a href="http://shtylman.com/localtunnel/">nodejs localtunnel</a>, <a href="http://pagekite.net">pagekite</a>, <a href="https://forwardhq.com/">forwardhq</a> etc.comes in. It makes the local server accessible over an IP (and port), on the internet. I did to have api driven tunnel server, which i could use to setup remote browser session debugging. But that story is for another time.</p>
<p>Check the <a href="http://github.com/ciju/gotunnel">Github repo</a> for installation and usage instructions.</p>
<p>Core idea of the solution is that a client from localhost could keep a connection with a server on the internet.</p>
<p>This connection could be used by server to forward requests. Gotunnel utilizes this by running a client on localhost. This Gotunnel Client connects to the Gotunnel Server accessible on the net. It also connects to the App server. Gotunnel Clients role is to receive requests from Gotunnel Server, and forward them to App Server.</p>
<p>Lets start with a (slightly incomplete) picture of the whole architecture. (Except for small changes, picture is copied from <a href="https://github.com/progrium/localtunnel/blob/master/PROTOCOL.md">Localtunnel protocol doc</a>). Keep this picture in mind, while we delve into more details.</p>
<pre><code class="language-py">.
             +--------------------+
             | Gotunnel Server    |
             |--------------------|         +---------+
             | Backend | Frontend |&#x3C;--------+ Browser |
             +---------|----------+         +---------+
                ^  ^^
                |  ||
                |  ||
         Control|  ||Proxy
      Connection|  ||Connections
                |  ||
         +------|  ||-----------------------------------+
         |   +--|--++----------+         +------------+ |
         |   | Gotunnel Client +-------->| App Server | |
         |   +-----------------+         +------------+ |
         |                                              |
         |                  localhost                   |
         +----------------------------------------------+
</code></pre>
<p>What we want is for the App Server to be accessible from (lets say) a browser. Since it can't be accessed from outside the localhost, we have a client in localhost, which is connected with the Gotunnel server, and can connect to the App Server whenever needed.</p>
<p>Lets examine the case where only a single App Server needs to be made accessible on the net. The client could (at startup) connect the Gotunnel Server, and setup a Control Connection. Gotunnel Server, on receiving a request from Browser, would let Gotunnel Client know about it, via the Control Connection. Gotunnel Client would respond by creating a new connection with Gotunnel Server, which will we used as a Proxy Connection. Gotunnel Server would then tunnel the request via the Proxy Connection. All this is happening at the TCP level (and hence supporting HTTP/S &#x26; WebSocket).</p>
<p>To support multiple clients, Gotunnel would have to differentiate between requests for different App Servers, and keep account of Control Connections associated with respective Clients. Like <a href="http://progrium.com/localtunnel/">Localtunnel</a>, Gotunnel Server associates Clients (and in turn App Servers) with subdomains of the Server.</p>
<p>To look at it from another perspective, lets consider the lifecycle of Gotunnel Server and Client. Lets first look at Gotunnel Client. When a client connects to Gotunnel Server, server sends back a subdomain. This is useless to client itself, except to show it on console, for you to share it with others. Any request to that subdomain, server will route to the particular client. And client in turn, to the App server. Response goes back via the same connections.</p>
<p>Gotunnel Server is basically listening for two kinds of connections. Its listening for subdomain requests, to route to the particular client, associated with the subdomain. And its listening for connections from new clients, and when a new client connects it assigns the requested (or newly generated) subdomain to the particular client.</p>
<p>All the connection routing etc is done at TCP level. What this means is that the connection, in most parts, doesn't have to worry about the application layer protocol. Example, there is no separate code to support WebSocket. The only part where we have to deal with the application layer level protocol intricacies, is to get the <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Client_request">Host</a>. We need the host to get the subdomain, for the request. In case of HTTP and WebSocketWebSocket starts as a HTTP connection. So, the process of getting HOST is same for both., we do this by parsing first few hundred bytes of the request, to get the headers. HTTPS is more difficult. In case of HTTPS headers themselves are (or might be?) encrypted. But in our trials, the host string was still sent in ascii. So, if we can't parse headers, we just fall back to a regular expression match. Since the domain of the request is known, we can be somewhat specific in the regular expression. In other words, if you dont need subdomain parsing, (ex: a server which to which only one client can be connected), then there is no need for parsing. And he solution can be simpler.</p>
<p>Routing at TCP level has atleast one problem. It might not be possible to do connection pooling. Ex: We don't know when a request or response ends (unless we deal with the application layer protocol). So, the only way to know the end of connection, is if the TCP connection is closed. In other words, we won't be able use the same TCP connection to tunnel multiple TCP connections.</p>]]></content:encoded>
    </item>
    <item>
      <title>Four Cards, Gnome, and Goblin</title>
      <description>Four Cards, Gnome, and Goblin</description>
      <link>https://ciju.in/writings/2008-07-24-four-cards-gnome-and-goblin</link>
      <guid isPermaLink="true">https://ciju.in/writings/2008-07-24-four-cards-gnome-and-goblin</guid>
      <pubDate>Thu, 24 Jul 2008 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>Another interesting puzzle, <a href="http://gurmeet.net/puzzles/tumblers-on-a-rotating-table/">Four Cards</a> from <a href="http://gurmeet.net/puzzles/">Gurmeet Manku's Puzzle collection</a></p>
<blockquote>
<p>Four cards are placed on a square table, one card at each corner. A
blind gnome and an evil goblin take turns to play the following game.
The blind gnome gets to choose a subset of the four cards and flip
them simultaneously. If all four cards are face up, he wins the game.
Otherwise, the evil goblin get to rotate the table by an amount of his
choice. Show that for any initial configuration of cards chosen by the
evil goblin, the blind gnome can win the game in a finite number of
steps with a deterministic strategy.</p>
</blockquote>
<p>To get a better start with the problem, let me simplify it a little. In the modified problem, the gnome wins if all cards face the same. Example, either all cards face up, or all cards face down. This is a simpler problem.</p>
<p>Now lets take the simplified version. Consider the 4 cards on the table. Removing all the symmetrical configurations, there are just three distinct configurations of cards on the table, apart from the winning configuration. For notational convenience, I will use D for a cards facing down, U for a card facing up.</p>
<pre><code class="language-text">Case 1: Just one face differs from others.
   |D D|
   |D C|

Case 2: two cards up and two down on the same side.
   |D C|
   |D C|

Case 3: Two cards up and two down diagonally.
   |D C|
   |C D|
</code></pre>
<p>The gnome has to know about which kinds of flips matter. He cant judge about which cards to flip, so he only has the option of differentiating flips by count and orientation. Again, there are just 3 kinds of flips that matter. Flipping one of them, flipping 2 diagonally, or flipping 2 sideways.</p>
<p>Now map the transformations possible by these flips on the 3 types of configuration.</p>
<pre><code class="language-plain">1 &#x3C;-diag-> 1
1 &#x3C;-side-> 1
1 &#x3C;-one->  {2, 3, win}

2 &#x3C;-diag-> 2
2 &#x3C;-side-> {3, win}
2 &#x3C;-one->  1

3 &#x3C;-diag-> win
3 &#x3C;-side-> 2
3 &#x3C;-one->  1
</code></pre>
<p>Lets map the transformations for a the winning game. We would have to keep track of set possible cases that will occur in each transformation. Observe that case 1 is most distant from wining, case 2 the second most, and case 3 the closest. What we would like to achieve is a way to <em>reduce the possible number of configuration</em>, as we work with transformations. So if there is a case 3, finish off with it and so on. If a win happens in between, game ends automatically. So we only have to consider in the cases otherwise. Here's the solution</p>
<pre><code class="language-text">{1,2,3} &#x3C;-diag-> {1,2} &#x3C;-side-> {1,3} &#x3C;-diag-> {1} &#x3C;-one-> {2,3} &#x3C;-diag-> {2} &#x3C;-side-> {3} &#x3C;-diag-> {sure win}
</code></pre>
<p>To the main problem. If the only winning position is all faces up, the game essentially remains the same except the number of configurations and transformations. Now the number of combinations that matter is 5. The types of transformations remain the same, except for the special case of flipping all the cards. Its only used in one case. For rest of the configurations, flipping all doesn't change anything. Here's a list cases and the transformations which are useful. I am showing win case if its the only case.</p>
<pre><code class="language-text">Case 1:
   |U U|   1 &#x3C;-diag-> {1,2} ; 1 &#x3C;-side-> {1,2} ; 1 &#x3C;-one-> {3,4,5}
   |U D|

Case 2:
   |D D|   2 &#x3C;-diag-> {1,2} ; 2 &#x3C;-side-> {1,2} ; 1 &#x3C;-one-> {3,4,5}
   |D U|

Case 3:
   |U U|   3 &#x3C;-diag-> {3} ; 3 &#x3C;-side-> {4,5} ; 3 &#x3C;-one-> {1,2}
   |D D|

Case 4:
   |U D|   4 &#x3C;-diag-> {5} ; 4 &#x3C;-side-> {3} ; 4 &#x3C;-one-> {1,2}
   |D U|

Case 5:
   |D D|   5 &#x3C;-diag-> {4} ; 5 &#x3C;-side-> {3} ; 5 &#x3C;-one-> {2} ; 5 &#x3C;-flipall-> {sure win}
   |D D|
</code></pre>
<p>Now the solution for the original problem. What we would try to do it get all the cases to case 5, and then flip-all. Flip all is represented by fa.</p>
<pre><code class="language-text">{1,2,3,4,5}
&#x3C;-fa->   {1,2,3,4}
&#x3C;-diag-> {1,2,3,5}
&#x3C;-fa->   {1,2,3}
&#x3C;-side-> {1,2,4,5}
&#x3C;-fa->   {1,2,4}
&#x3C;-diag-> {1,2,5}
&#x3C;-fa->   {1,2}
&#x3C;-one->  {3,4,5}
&#x3C;-fa->   {3,4}
&#x3C;-diag-> {3,5}
&#x3C;-fa->   {3}
&#x3C;-side-> {4,5}
&#x3C;-fa->   {4}
&#x3C;-diag-> {5}
&#x3C;-fa->   {sure win}
</code></pre>
<p>Essentially, what we did is to take the following action at each step.</p>
<ul>
<li><strong>if:</strong> 5 one of possible states then flip-all</li>
<li><strong>else if:</strong> 4 among the possible states flip diagonal</li>
<li><strong>else if:</strong> 3, flip side</li>
<li><strong>else if:</strong> 2 or 1, flip one</li>
</ul>
<p>So gnome can win the game in 15 steps or less.</p>]]></content:encoded>
    </item>
    <item>
      <title>Splitting PDF Slides: 4-up to 1-up</title>
      <description>Splitting PDF Slides: 4-up to 1-up</description>
      <link>https://ciju.in/writings/2008-07-21-splitting-pdf-slides-4-up-to-1-up</link>
      <guid isPermaLink="true">https://ciju.in/writings/2008-07-21-splitting-pdf-slides-4-up-to-1-up</guid>
      <pubDate>Mon, 21 Jul 2008 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>Many 4-up slides are quite inconvenient for onscreen reading. And quite a few times, no other options are available. Here is a small and rough solution to the problem. First, you need to have <a href="http://www.python.org">Python</a> on your system. Download and extract the <em><a href="http://pybrary.net/pyPdf/">pyPdf</a></em> package. Download code from <a href="http://github.com/ciju/split-pdf-slides/raw/master/split-pdf.py">here</a>, to the source directory of the <em>pyPdf</em> package and run it from there. To use it give input and output file names and number of slides per page (&#x3C;row> &#x3C;col>) on the input pdf, and the program should work. If the slides don't show up in proper order, give the order of slides you want, at the end of command line.</p>
<p>If you would like to install the <em>pyPdf</em> package, you would have to copy <em>page4eachXobj</em> function to <em>PageObject</em> in <em>pdf.py</em> and add 'import copy' to the top of the file. While copying, be careful with indentation. After this, my file could be placed anywhere.</p>
<p>The file has two methods to convert 4-up/6-up/... slides to a more convenient one slide per page. First method <em>adv_slide_split</em> gives better output(ex: similar to original slides), but works in very few cases. This method doesn't use the row column information, given at input. Second method <em>slide_split</em> works by dividing the page into equal sized pages, usually not as good as the original 1-up, but works with most of the cases. If possible, the program will use the first method, else the second one.</p>
<p>Rest of the post is about my experience with the problem. Not a required read for using the program.</p>
<p>First off, you need to know that pdf is, in simple words, a collection of data and instructions on how to present the data. Its different/complex from markup languages, as it has to deal with various devices, like printer, and not just the web. And has to be able to represent complex typography and graphics etc, in a concise way.</p>
<p>A pdf file contains lots of <em>&#x3C;num> 0 obj</em> and <em>endobj</em> pairs in it. Called <em>Indirect Objects</em>, these are used as a reference to objects in the file. Example, from collection of pages to postscript instructions and fonts and colors etc. There are few kinds and types of objects. Name objects starting with '/',  dictionary objects enclosed in '&#x3C;&#x3C;' '>>' pair, array objects in '[' ']' pair, stream object mostly used for data. For our purpose, these should be enough. Indirect objects making it easy to share objects among objects! <em>&#x3C;num> 0 R</em> is used to refer to an object. I have skimmed, skipped and missed much of the information. If you are interested, read the <a href="https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf">manual</a>. Chapter 3 is the most relevant part.</p>
<p>I was lucky enough to stumble upon a nicely generated slide to dig into, similar to <a href="http://www.cs.uiuc.edu/class/su06/cs421/lectures/01-CourseIntro-4up.pdf">this one </a>. A casual look into the raw file shows <em>/Page</em> tags.</p>
<pre><code class="language-ps">7 0 obj &#x3C;&#x3C;
/Type /Page
/Contents 8 0 R
/Resources 6 0 R
/MediaBox [0 0 841.89 595.276]
/Parent 9 0 R
>> endobj
</code></pre>
<p>With the <em>/Page</em> tags are <em>/Resources</em> with an object reference. The referred object is <em>/XObject</em> dictionary with references to 4 objects.</p>
<pre><code class="language-ps">6 0 obj &#x3C;&#x3C;
/XObject &#x3C;&#x3C;/Im2 2 0 R /Im3 3 0 R /Im4 4 0 R /Im5 5 0 R>>
/ProcSet [ /PDF ]
>> endobj
</code></pre>
<p>I removed 3 of them from the dictionary. The pdf file indeed showed only the remaining slide (with empty space for others), while xpdf complained about missing references. Manual mentions that <em>/XObject</em> <em>names</em> external objects. That means the names must be used somewhere else. But searching for those names show only the <em>/XObject</em> entries.  Page objects entry in manual mentions that <em>/Contents</em> is where the contents of page are described. But <em>/Contents</em> refers to a <em>/FlateDecode</em> stream (essentially a zipped binary of the description of page). Fortunately, I didn't have to look inside it. Need was just to display those external references, one on each page. The external references in <em>/XObject</em> themselves were of type <em>/XObject</em>.</p>
<pre><code class="language-ps">2 0 obj &#x3C;&#x3C;
/Type /XObject
...
>>
stream
...
endstream
endobj
</code></pre>
<p>Manual mentions details about the type and how to display it. To have a proof of concept, I changed a <em>Page</em> objects <em>/Contents</em> key to point to a custom stream, and <em>/Page</em> to contain one slide. <a href="http://ciju.files.wordpress.com/2008/07/test.pdf">Here's</a> the output. More work was needed to convert the whole document. New pages would be needed, as each page would have to be replaced with 4 new once, references would have to be updated, page counts at all levels need to be updated, xref would have to be updated etc.</p>
<p>This needed considerably more effort than I intended. Again, fortunately, I came across <em>pyPdf</em>. Its a versatile library. In the <em>README</em> itself, it shows the trick of cropping a page (Although I would call it zooming). So all I had to do was to copy page 4 times and only show relevant part in each of them.</p>
<p>The above method doesn't depend on slides being available as separate resources, but used the concept of <em>MediaBox</em>. So it would work with most pdf files. But, if the slides are available as separate resources, the earlier method results in a pdf closer to the original sources. For comparison of the output, here are slides generated with method using <a href="http://ciju.files.wordpress.com/2008/07/adv-ss-out.pdf">XObject</a> and the <a href="http://ciju.files.wordpress.com/2008/07/ss-out.pdf">MediaBox one</a>. Fortunately the library also makes it easier for me to implement the earlier <em>/XObject</em> method. It depends on the internals of <em>pyPdf</em> implementation. So either you would have to copy it to the <em>pyPdf</em> source file, or import all the internal classes of <em>pyPdf</em>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Google Treasure Hunt</title>
      <description>Google Treasure Hunt</description>
      <link>https://ciju.in/writings/2008-06-03-google-treasure-hunt</link>
      <guid isPermaLink="true">https://ciju.in/writings/2008-06-03-google-treasure-hunt</guid>
      <pubDate>Tue, 03 Jun 2008 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>Two problems from Google treasure hunt, which although not quite tough, but nevertheless were interesting.</p>
<p>One was about a <a href="http://treasurehunt.appspot.com/historic/robot/">robot</a> starting from top left corner of a matrix, trying to reach the bottom right corner. Robot could only go right or down. The problem was to find the number of unique possible paths. My first thought was to use dynamic programming. Some more thoughts, and I was able to see a pattern in the solution. The basic idea was, like in dynamic programming, to solve the smaller problems first. The observation was that the paths could be calculated one level at a time. The paths are calculated along a line parallel to the anti-diagonal, as it sweeps through the matrix from destination cell towards the starting cell.</p>
<p>Here's the code doing just that.</p>
<pre><code class="language-cpp">int main(int argc, char ** argv) {
  int r, c, i, j, diag;
  unsigned long long *pa;
  assert(argc == 3);

  r = atoi(argv[1]);
  c = atoi(argv[2]);

  diag = r &#x3C; c ? r : c;
  pa = calloc( diag, sizeof pa[0] );

  for (i=0;i&#x3C;diag;i++)
    pa[i] = 0;
  pa[0] = 1;

  for (i=0;i&#x3C;r+c-2;i++)
    for (j=diag-1;j>0;j--)
      pa[j] = pa[j] + pa[j-1];

  printf("paths %llu \n", pa[diag-1]);

  return 0;
}
</code></pre>
<p>The implementation worked for small inputs. But for the actual input, long long was not enough (and assumably intended by the problem designer). Some more thoughts about the process, and the insight came. The pattern seemed to be familiar, although incomplete. It was the <a href="en.wikipedia.org/wiki/Pascal&#x27;s_triangle">Pascal's triangle </a>. It was easy to find out the entry needed from the Pascal's triangle and its corresponding value (<img src="https://math.vercel.app/?from=%5Cmathrm%7BC%7D%5E%7Bn%2Bm-2%7D_%7Bn-1%7D" alt="\mathrm{C}^{n+m-2}_{n-1}" style="display: inline; vertical-align: middle;" />). But still, to calculate it, would need more precision than whats available with C data types (otherwise my program would have given the answer). <a href="http://www.google.co.in/search?q=91!%2F(30!*60!)">Google</a> also didn't help. Looking for bignum library, lead me to this <a href="http://gmplib.org/#try"> expression calculator</a>. All I had to do was fill in the equation and copy paste the solution.</p>
<p>The other one was the <a href="http://treasurehunt.appspot.com/historic/primes/"> last problem</a>. Here is a verbatim instance of the problem.</p>
<blockquote>
<p>Find the smallest number that can be expressed as
the sum of 3 consecutive prime numbers,
the sum of 35 consecutive prime numbers,
the sum of 553 consecutive prime numbers,
the sum of 829 consecutive prime numbers,
and is itself a prime number.
For example, 41 is the smallest prime number that can be expressed as
the sum of 3 consecutive primes (11 + 13 + 17 = 41) and
the sum of 6 consecutive primes (2 + 3 + 5 + 7 + 11 + 13 = 41).</p>
</blockquote>
<p>The smaller sequence would always end with larger primes, than the longer sequence. Reason being that the same sum is distributed in a smaller set of consecutive primes. How does that help? Slide the smallest sequence to include the next prime, and simultaneously, update all later sequences to have sum greater than or equal to sequences smaller than them. Here's a little cryptic code for the solution.</p>
<pre><code class="language-cpp">struct cseq {
  int seql;			/* seq len */
  int seqt;			/* seq top */
  int seqs;			/* seq sum */
} *sa;

void slide_sequence(struct cseq *s) {
  s->seqt++;
  s->seqs -= prime[s->seqt - s->seql];
  s->seqs += prime[s->seqt];
}

int align_to_sum(struct cseq *s, int sum) {
  while (s->seqs &#x3C; sum) slide_sequence(s);

  return s->seqs == sum;
}

int main() {
  /* initialize sa and primes array and other variables. */

  for each consecutive prime {
    /* invar: bigger sequences have sum >= smaller once. */
    eqcnt=0;

    slide_sequence( &#x26;(sa[0]) );

    for (j=1;j&#x3C;scnt;j++)
      if (align_to_sum(&#x26;(sa[j]), sa[0].seqs))
        eqcnt++;

    if (eqcnt == scnt-1) {
      if (isprime(sa[0].seqs) {
        print_sequence(sa, scnt);
        break;
      } else {
        continue;
      }
    }
  }
}
</code></pre>
<p>I used an already generated list of primes, from <a href="http://www.1falsemove.50megs.com/primespage.html">here </a>.</p>
<p>Here are the timing details.</p>
<pre><code class="language-bash">$time ./a.out
seq:     3, start: 221709, end: 221711, sum: 9221231
seq:    35, start: 23088, end: 23122, sum: 9221231
seq:   553, start:  1650, end:  2202, sum: 9221231
seq:   829, start:   930, end:  1758, sum: 9221231

real   0m0.210s
user   0m0.208s
sys    0m0.000s
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Subtleties Of Programming</title>
      <description>Be careful in swapping with XOR</description>
      <link>https://ciju.in/writings/2008-05-30-subtleties-of-programming</link>
      <guid isPermaLink="true">https://ciju.in/writings/2008-05-30-subtleties-of-programming</guid>
      <pubDate>Fri, 30 May 2008 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<p>While coding for the <a href="http://ciju.wordpress.com/2008/05/28/problem-23-7/%22">problem-2.3-7</a>, some how I was not in my default mode of not thinking while coding. To test my programs I was writing a random array generator. One part of it was to swap two array entries. Now, the most straight forward way to swap two array elements is</p>
<pre><code class="language-c">int tmp = arr[i];
arr[i]  = arr[r];
arr[r]  = tmp;
</code></pre>
<p>But, knowing the xor method, I thought why not save a variable. Basically, if a and b are to be swapped, then the code suffices.</p>
<pre><code class="language-c">a ^= b;
b ^= a;
a ^= b;
</code></pre>
<p>So now the question is, would this work on an array. Ex.</p>
<pre><code class="language-c">arr[i] ^= arr[r];
arr[r] ^= arr[i];
arr[i] ^= arr[r];
</code></pre>
<p>Here's a subtle bug. If i and r are same, then it won't. The reason being that we loose the original value. If both indexes are same, the same array entry would be xor'ed with itself. <a href="http://en.wikipedia.org/wiki/XOR_swap_algorithm">Wiki page</a> explains it better, and why it should be avoided. Again, I learn the evils of premature optimization. Subtleties of programming!</p>]]></content:encoded>
    </item>
    <item>
      <title>CLRS - problem 2.3-7</title>
      <description>Solution to problem 2.3-7, Introduction to Algorithms, CLRS, 2nd ed.</description>
      <link>https://ciju.in/writings/2008-05-28-problem-23-7</link>
      <guid isPermaLink="true">https://ciju.in/writings/2008-05-28-problem-23-7</guid>
      <pubDate>Wed, 28 May 2008 00:00:00 GMT</pubDate>
      <author>ciju@ciju.in (ciju)</author>
      <category>Technology</category>
      <dc:creator>ciju</dc:creator>
      <content:encoded><![CDATA[<h2>Problem:</h2>
<p>We are given a set <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" /> of <img src="https://math.vercel.app/?from=n" alt="n" style="display: inline; vertical-align: middle;" /> integers, and another integer <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" />. And we need to find out if there exists two integers in the set <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" /> such that there sum is <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" />.</p>
<h2>Approach:</h2>
<p>The straight forward answer is to calculate sum for each possible pair of elements in <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" />, and see if any of them matches with <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" />.</p>
<p>Note that the sum of the smallest element and the largest element in <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" />, will be the median of sums possible with pairs of elements in <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" />. If <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" />, is less than this sum, then the largest element of <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" /> could not be in the pair we are searching for. Similarly, if <img src="https://math.vercel.app/?from=x" alt="x" style="display: inline; vertical-align: middle;" /> is larger than the required sum, then the smallest element from <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" /> will not be in the pair we are searching for. The same method could be applied to the subproblem(the remaining list).</p>
<p>At each stage we have to calculate the smallest and largest element in the list. We could solve this for each subproblem in <img src="https://math.vercel.app/?from=%5Cmathcal%7BO%7D(n)" alt="\mathcal{O}(n)" style="display: inline; vertical-align: middle;" />, or we could sort the set <img src="https://math.vercel.app/?from=S" alt="S" style="display: inline; vertical-align: middle;" /> initially, and then access the smallest and largest elements in <img src="https://math.vercel.app/?from=%5Cmathcal%7BO%7D(1)" alt="\mathcal{O}(1)" style="display: inline; vertical-align: middle;" />. The second approach solves the problem in <img src="https://math.vercel.app/?from=%5Cmathcal%7BO%7D(n%5Clog%7B%7Dn)" alt="\mathcal{O}(n\log{}n)" style="display: inline; vertical-align: middle;" />.</p>
<h2>Coding the approach:</h2>
<p>As you might have noticed, the solution is a recursive one. But it
doesn't have to be coded that way. The recursive solution could be
easily converted to an iterative one, as shown below. I have skipped
the much of the code, just to present heart of the method.</p>
<pre><code class="language-c">int sum_check(int *arr, int n, int x)
{
  int u, l, s;
  u=0;l=n-1;

  while (u&#x3C;l) {
    s = arr[u]+arr[l];
    if (x &#x3C; s)
      l--;
    else if (x > s)
      u++;
    else
      return 1;
  }

 return 0;
}
</code></pre>
<p>But lets see the recursive approach also.</p>
<pre><code class="language-c">int sum_check_rec(int *arr, int n, int x)
{
  int s = arr[0] + arr[n-1];

  if (n == 1) return 0;
  if (x == s) return 1;

  return sum_check_rec(arr + (x&#x3C;s ? 0 : 1), n-1, x);
}
</code></pre>
<p>I would not advice you on which approach you should use, but I would like to mention that the usual case against recursion doesn't hold here. At least GCC4.* optimizes tail recursions with optimization level of O1 or larger. Basically, the fact to notice is that the return value of the recursive call is not used by the recursively calling function. Compiler could take the value from the end of recursion to the function which called this recursive function(in essence). Compiler takes over the job of converting the tail recursive call to an iterative version. To make sure that compiler did optimize away the recursion, run the function on an array of size, lets say, 10000. Without optimization, execution of program would give stack overflow error.</p>]]></content:encoded>
    </item>
  </channel>
</rss>