<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Advogato blog for ssp</title>
    <link>http://www.advogato.org/person/ssp/</link>
    <description>Advogato blog for ssp</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Tue, 21 May 2013 18:47:35 GMT</pubDate>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Fast Multiplication of Normalized 16 bit Numbers with SSE2</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=26</link>
      <guid>http://ssp.impulsetrain.com/2011-07-03_Fast_Multiplication_of_Normalized_16_bit_Numbers_with_SSE2.html</guid>
      <description>&lt;p&gt;If you are compositing pixels with 16 bits per component, you often
need this computation:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;uint16_t a, b, r;

r = (a * b + 0x7fff) / 65535;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;There is a well-known way to do this quickly without a division:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;uint32_t t;

t = a * b + 0x8000;

r = (t + (t &amp;gt;&amp;gt; 16)) &amp;gt;&amp;gt; 16;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Since we are compositing pixels we want to do this with SSE2
instructions, but because the code above uses 32 bit arithmetic, we
can only do four operations at a time, even though SSE registers have
room for eight 16 bit values. Here is a direct translation into SSE2:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;a = punpcklwd (a, 0);
b = punpcklwd (b, 0);
a = pmulld (a, b);
a = paddd (a, 0x8000);
b = psrld (a, 16);
a = paddd (a, b);
a = psrld (a, 16);
a = packusdw (a, 0);
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;But there is another way that better matches SSE2:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;uint16_t lo, hi, t, r;

hi = (a * b) &amp;gt;&amp;gt; 16;
lo = (a * b) &amp;amp; 0xffff;

t = lo &amp;gt;&amp;gt; 15;
hi += t;
t = hi ^ 0x7fff;

if ((int16_t)lo &amp;gt; (int16_t)t)
    lo = 0xffff;
else
    lo = 0x0000;

r = hi - lo;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This version is better because it avoids the unpacking to 32
bits. Here is the translation into SSE2:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;t = pmulhuw (a, b);
a = pmullw (a, b);
b = psrlw (a, 15);
t = paddw (t, b);
b = pxor (t, 0x7fff);
a = pcmpgtw (a, b);
a = psubw (t, a);
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This is not only shorter, it also makes use of the full width of the
SSE registers, computing eight results at a time.&lt;/p&gt;
&lt;p&gt;Unfortunately SSE2 doesn&#x2019;t have 8-bit variants of &lt;code&gt;pmulhuw&lt;/code&gt;, &lt;code&gt;pmullw&lt;/code&gt;, and
&lt;code&gt;psrlw&lt;/code&gt;, so we can&#x2019;t use this trick for the more common case where
pixels have 8 bits per component.&lt;/p&gt;
&lt;p&gt;Exercise: Why does the second version work?&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Sysprof 1.1.8</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=25</link>
      <guid>http://ssp.impulsetrain.com/2011-07-15_Sysprof_1_1_8.html</guid>
      <description>&lt;p&gt;A new version &lt;a href="http://sysprof.com/sysprof-1.1.8.tar.gz" &gt;1.1.8&lt;/a&gt; of
&lt;a href="http://sysprof.com" &gt;Sysprof&lt;/a&gt; is out.&lt;/p&gt;
&lt;p&gt;This is a release candidate for 1.2.0 and contains mainly bug fixes.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Gamma Correction vs. Premultiplied Pixels</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=24</link>
      <guid>http://ssp.impulsetrain.com/2011-08-10_Gamma_Correction_vs__Premultiplied_Pixels.html</guid>
      <description>&lt;p&gt;Pixels with 8 bits per channel are normally sRGB encoded because that
allocates more bits to darker colors where human vision is the most
sensitive. (Actually, it&#x2019;s really more of a historical accident, but
sRGB nevertheless remains useful for this reason). The relationship
between sRGB and linear RGB is that you get an sRGB pixel by raising
each component of a linear pixel to the power of &lt;mathjax&gt;$1/2.2$&lt;/mathjax&gt;.&lt;/p&gt;
&lt;p&gt;A lot of graphics software does alpha blending directly on these sRGB
pixels using alpha values that are linearly coded (ie., an alpha value
of 0 means no coverage, 0.5 means half coverage, and 1 means full
coverage). Because alpha blending is best done with premultiplied
pixels, such systems store pixels in this format:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;[ alpha,  alpha * red_s,  alpha * green_s,  alpha * blue_s ]
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;where alpha is linearly coded, and (&lt;code&gt;red_s&lt;/code&gt;, &lt;code&gt;green_s&lt;/code&gt;, &lt;code&gt;blue_s&lt;/code&gt;) are
sRGB coded. As long as you are happy with blending in sRGB, this works
well. Also, if you simply discard the alpha channel of such pixels and
display them directly on a monitor, it will look as if the pixels were
alpha blended (in the sRGB space) on top of a black background, which
is the desired result.&lt;/p&gt;
&lt;p&gt;But what if you want to blend in linear RGB? If you use the format
above, some expensive conversions will be required. To convert to
premultiplied linear, you have to first divide by alpha, then raise
each color to 2.2, then multiply by alpha. To convert back, you must
divide by alpha, raise to &lt;mathjax&gt;$1/2.2$&lt;/mathjax&gt;, then multiply with alpha.&lt;/p&gt;
&lt;p&gt;The conversions can be avoided if you store the pixels linearly, ie.,
keeping the premultiplication, but coding red, green, and blue
linearly instead of as sRGB. This makes blending fast, but the
downside is that you need deeper pixels. With only 8 bits per pixel,
the linear coding loses too much precision in darker tones. Another
problems is that to display these pixels, you will either have to
convert them to sRGB, or if the video card can scan them out directly,
you have to make sure that the gamma ramp is set to compensate for the
fact that the monitor expects sRGB pixels.&lt;/p&gt;
&lt;p&gt;Can we get the best of both worlds? Yes. The format to use is this:&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;[ alpha,  alpha_s * red_s,  alpha_s * green_s,  alpha_s * blue_s ]
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;That is, the alpha channel is stored linearly, and the color channels
are stored in sRGB, premultiplied with the alpha value raised to
1/2.2. Ie., the red component is now&lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;(red * alpha)^(1/2.2),
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;where before it was &lt;/p&gt;
&lt;div&gt;
  &lt;pre&gt;alpha * red^(1/2.2).
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;It is sufficient to use 8 bits per channel with this format because of
the sRGB encoding. Discarding the alpha channel and displaying the
pixels on a monitor will produce pixels that are alpha blended (in
linear space) against black, as desired.&lt;/p&gt;
&lt;p&gt;You can convert to linear RGB simply by raising the R, G, and B
components to 2.2, and back by raising to &lt;mathjax&gt;$1/2.2$&lt;/mathjax&gt;. Or, if you feel
like cheating, use an exponent of 2 so that the conversions become a
multiplication and a square root respectively.&lt;/p&gt;
&lt;p&gt;This is also the pixel format to use with texture samplers that
implement the sRGB OpenGL extensions
(&lt;a href="http://www.opengl.org/registry/specs/EXT/texture_sRGB.txt" &gt;textures&lt;/a&gt;
and
&lt;a href="http://www.opengl.org/registry/specs/ARB/framebuffer_sRGB.txt" &gt;framebuffers&lt;/a&gt;). These
extensions say precisely that the R, G, and B components are raised to
2.2 before texture filtering, and raised to 1/2.2 after the final
raster operation.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Over is not Translucency</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=23</link>
      <guid>http://ssp.impulsetrain.com/2011-09-26_Over_is_not_Translucency.html</guid>
      <description>&lt;p&gt;The &lt;a href="http://keithp.com/~keithp/porterduff/&amp;gt;" &gt;Porter/Duff&lt;/a&gt; Over
operator, also known as the &#x201C;Normal&#x201D; blend mode in Photoshop, computes
the amount of light that is reflected when a pixel partially covers
another:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img alt="The Porter/Duff OVER operator" src="http://ssp.impulsetrain.com/bg-fg.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The fraction of bg that is covered is denoted alpha. This operator is
the correct one to use when the foreground image is an opaque mask
that partially covers the background:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img alt="Red mask on blue background" src="http://ssp.impulsetrain.com/big-over1.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A photon that hits this image will be reflected back to your eyes by
either the foreground or the background, but not both. For each
foreground pixel, the alpha value tells us the probability of each:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$a \cdot \text{fg} + (1 - a) \cdot \text{bg}$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the definition of the Porter/Duff Over operator for
non-premultiplied pixels.&lt;/p&gt;
&lt;p&gt;But if alpha is interpreted as &lt;em&gt;translucency,&lt;/em&gt; then the Over operator
is not the correct one to use. The Over operator will act as if each
pixel is partially covering the background:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img alt="" src="http://ssp.impulsetrain.com/shaped-over.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Which is not how translucency works. A translucent material reflects
some light and lets other light through. The light that is let through
is reflected by the background and &lt;em&gt;interacts with the foreground
again&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img align="right" src="http://ssp.impulsetrain.com/Translucency.png" alt="" width="256" height="329"/&gt;Let&#x2019;s look at this in more detail. Please follow along
in the diagram to the right. First with probability &lt;mathjax&gt;$a$&lt;/mathjax&gt;, the
photon is reflected back towards the viewer:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$a \cdot \text{fg}$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With probability &lt;mathjax&gt;$(1 - a)$&lt;/mathjax&gt;, it passes through the foreground, hits the
background, and is reflected back out. The photon now hits the
&lt;em&gt;backside&lt;/em&gt; of the foreground pixel. With probability &lt;mathjax&gt;$(1 - a)$&lt;/mathjax&gt;, the
foreground pixel lets the photon back out to the viewer. The result so
far:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$
\begin{align*}
&amp;amp;a\cdot \text{fg} \\
+&amp;amp;(1 - a) \cdot \text{bg} \cdot (1 - a)
\end{align*}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But we are not done yet, because with probability &lt;mathjax&gt;$a$&lt;/mathjax&gt; the foreground pixel reflects the photon once again back towards the background pixel. There it will be reflected, hit the backside of the foreground pixel again, which lets it through to our eyes with probability &lt;mathjax&gt;$(1 - a)$&lt;/mathjax&gt;. We get another term where the final &lt;mathjax&gt;$(1 - a)$&lt;/mathjax&gt; is replaced with &lt;mathjax&gt;$a \cdot \text{fg} \cdot \text {bg} \cdot (1 - a)$&lt;/mathjax&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$
\begin{align*}
&amp;amp;a\cdot \text{fg} \\
+&amp;amp;(1 - a) \cdot \text{bg} \cdot (1 - a)\\
+&amp;amp;(1 - a) \cdot \text{bg} \cdot a \cdot \text{fg} \cdot \text{bg} \cdot (1 - a)
\end{align*}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And so on. In each round, we gain another term which is identical to
the previous one, except that it has an additional &lt;mathjax&gt;$a \cdot \text{fg}
\cdot \text{bg}$&lt;/mathjax&gt; factor:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$
\begin{align*}
&amp;amp;a\cdot \text{fg} \\
+&amp;amp;(1 - a) \cdot \text{bg} \cdot (1 - a)\\
+&amp;amp;(1 - a) \cdot \text{bg} \cdot a \cdot \text{fg} \cdot \text{bg} \cdot (1 - a)\\
+&amp;amp;(1 - a) \cdot \text{bg} \cdot a \cdot \text{fg} \cdot \text{bg} \cdot a \cdot \text{fg} \cdot \text{bg} \cdot (1 - a) \\
+&amp;amp;\cdots
\end{align*}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;or more compactly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
a \cdot \text{fg} + (1 - a)^2 \cdot \text{bg} \cdot
\sum_{i=0}^\infty (a \cdot \text{fg} \cdot \text{bg})^i
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Because we are dealing with pixels, both &lt;mathjax&gt;$a$&lt;/mathjax&gt;, &lt;mathjax&gt;$\text{fg}$&lt;/mathjax&gt;, and
&lt;mathjax&gt;$\text{bg}$&lt;/mathjax&gt; are less than 1, so the sum is a &lt;a href="http://en.wikipedia.org/wiki/Geometric_series" &gt;geometric
series&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
\sum_{i=0}^\infty x^i = \frac{1}{1 - x}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Putting them together, we get:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
a \cdot \text{fg} + \frac{(1 - a)^2 \cdot bg}{1 - a \cdot \text{fg} \cdot \text{bg}}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have sidestepped the issue of premultiplication by assuming that
background alpha is 1. The calculations with premultipled colors are
similar, and for the color components, the result is simply:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
r = \text{fg} + \frac{(1 - a_\text{fg})^2 \cdot \text{bg}}{1 - \text{fg}\cdot\text{bg}}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The issue of destination alpha is more complicated. With the Over
operator, both foreground and background are opaque masks, so the
light that survives both has the same color as the input light. With
translucency, the transmitted light has a different color, which means
the resulting alpha value must in principle be different for each
color component. But that&#x2019;s not possible for ARGB pixels. A similar
argument to the above shows that the resulting alpha value would be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
r = 1 - \frac{(1 - a)\cdot (1 - b)}{1 - \text{fg} \cdot \text{bg}}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where &lt;mathjax&gt;$b$&lt;/mathjax&gt; is the background alpha. The problem is the dependency on
&lt;mathjax&gt;$\text{fg}$&lt;/mathjax&gt; and &lt;mathjax&gt;$\text{bg}$&lt;/mathjax&gt;. If we simply assume for the purposes of
the alpha computation that &lt;mathjax&gt;$\text{fg}$&lt;/mathjax&gt; and &lt;mathjax&gt;$\text{bg}$&lt;/mathjax&gt; are equal to
&lt;mathjax&gt;$a$&lt;/mathjax&gt; and &lt;mathjax&gt;$b$&lt;/mathjax&gt;, we get this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
r = 1 - \frac{(1 - a)\cdot (1 - b)}{1 - a \cdot b}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which is equal to&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
a + \frac{(1 - a)^2 \cdot b}{1 - a \cdot b}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ie., exactly the same computation as the one for the color
channels. So we can define the &lt;em&gt;Translucency Operator&lt;/em&gt; as this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$\displaystyle
r = \text{fg} + \frac{(1 - a)^2 \cdot \text{bg}}{1 - \text{fg} \cdot \text{bg}}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;for all four channels.&lt;/p&gt;
&lt;p&gt;Here is an example of what the operator looks like. The image below is
what you will get if you use the Over operator to implement a
selection rectangle. Mouse over to see what it would look like if you
used the Translucency operator.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a&gt;
&lt;img src="http://ssp.impulsetrain.com/select-over1.png" alt=""/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Both were computed in linear RGB. Typical implementations will often
compute &lt;a href="select-over-srgb.png" &gt;the Over operator in sRGB&lt;/a&gt;, so that&#x2019;s
what see if you actually select some icons in Nautilus. If you want to
compare all three, open these in tabs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="select-over-srgb.png" &gt;Over, in sRGB&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="select-trans.png" &gt;Translucency, in linear RGB&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="select-over.png" &gt;Over, in linear RGB&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And for good measure, even though it makes zero sense to do this,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="select-trans-srgb.png" &gt;Translucency, in sRGB&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Sysprof 1.2.0</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=22</link>
      <guid>http://ssp.impulsetrain.com/2012-09-08_Sysprof_1_2_0.html</guid>
      <description>&lt;p&gt;A &lt;a href="https://lkml.org/lkml/2012/9/8/143" &gt;new stable release&lt;/a&gt;new stable
release of &lt;a href="http://sysprof.com/" &gt;Sysprof&lt;/a&gt; is now available. Download
&lt;a href="http://sysprof.com/sysprof-1.2.0.tar.gz" &gt;version 1.2.0&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Big-O Misconceptions</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=21</link>
      <guid>http://ssp.impulsetrain.com/2012-10-16_Big-O_Misconceptions.html</guid>
      <description>&lt;p&gt;In computer science and sometimes mathematics, big-O notation is used
to talk about how quickly a function grows while disregarding
multiplicative and additive constants. When classifying algorithms,
big-O notation is useful because it lets us abstract away the
differences between real computers as just multiplicative and additive
constants.&lt;/p&gt;
&lt;p&gt;Big-O is not a difficult concept at all, but it seems to be common
even for people who should know better to misunderstand some aspects
of it. The following is a list of misconceptions that I have seen in
the wild.&lt;/p&gt;
&lt;p&gt;But first a definition: We write&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$f(n) = O(g(n))$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;when &lt;mathjax&gt;$f(n) \le M g(n)$&lt;/mathjax&gt; for sufficiently large &lt;mathjax&gt;$n$&lt;/mathjax&gt;, for some positive constant &lt;mathjax&gt;$M$&lt;/mathjax&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 1:&lt;/b&gt; &#x201C;The Equals Sign Means Equality&#x201D;&lt;/p&gt;
&lt;p&gt;The equals sign in&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$f(n) = O(g(n))$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;is a widespread travestry. If you take it at face value, you can
deduce that since &lt;mathjax&gt;$5 n$&lt;/mathjax&gt; and &lt;mathjax&gt;$3 n$&lt;/mathjax&gt; are both equal to &lt;mathjax&gt;$O(n)$&lt;/mathjax&gt;, then &lt;mathjax&gt;$3 n$&lt;/mathjax&gt;
must be equal to &lt;mathjax&gt;$5 n$&lt;/mathjax&gt; and so &lt;mathjax&gt;$3 = 5$&lt;/mathjax&gt;.&lt;/p&gt;
&lt;p&gt;The expression &lt;mathjax&gt;$f(n) = O(g(n))$&lt;/mathjax&gt; doesn&#x2019;t type check. The left-hand-side
is a function, the right-hand-side is a &#x2026; what, exactly? There is no
help to be found in the definition. It just says &#x201C;we write&#x201D; without
concerning itself with the fact that what &#x201C;we write&#x201D; is total
nonsense.&lt;/p&gt;
&lt;p&gt;The way to interpret the right-hand side is as a &lt;em&gt;set&lt;/em&gt; of functions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$ O(f) = \{ g \mid g(n) \le M f(n) \text{ for some \(M &amp;gt; 0\) for large \(n\)}\}. $&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With this definition, the world makes sense again: If &lt;mathjax&gt;$f(n) = 3 n$&lt;/mathjax&gt;
and &lt;mathjax&gt;$g(n) = 5 n$&lt;/mathjax&gt;, then &lt;mathjax&gt;$f \in O(n)$&lt;/mathjax&gt; and &lt;mathjax&gt;$g \in O(n)$&lt;/mathjax&gt;, but there
is no equality involved so we can&#x2019;t make bogus deductions like
&lt;mathjax&gt;$3=5$&lt;/mathjax&gt;. We can however make the correct observation that &lt;mathjax&gt;$O(n)
\subseteq O(n \log n)\subseteq O(n^2) \subseteq O(n^3)$&lt;/mathjax&gt;, something
that would be difficult to express with the equals sign.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 2:&lt;/b&gt; &#x201C;Informally, Big-O Means &#x2018;Approximately Equal&#x2019;"&lt;/p&gt;
&lt;p&gt;If an algorithm takes &lt;mathjax&gt;$5 n^2$&lt;/mathjax&gt; seconds to complete, that algorithm is
&lt;mathjax&gt;$O(n^2)$&lt;/mathjax&gt; because for the constant &lt;mathjax&gt;$M=7$&lt;/mathjax&gt; and sufficiently large &lt;mathjax&gt;$n$&lt;/mathjax&gt;, &lt;mathjax&gt;$5
n^2 \le 7 n^2$&lt;/mathjax&gt;. But an algorithm that runs in constant time, say 3
seconds, is also &lt;mathjax&gt;$O(n^2)$&lt;/mathjax&gt; because for sufficiently large &lt;mathjax&gt;$n$&lt;/mathjax&gt;, &lt;mathjax&gt;$3 \le
n^2$&lt;/mathjax&gt;.&lt;/p&gt;
&lt;p&gt;So informally, big-O means &lt;em&gt;approximately less than or equal&lt;/em&gt;,
not &lt;em&gt;approximately equal&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If someone says &#x201C;Topological Sort, like other sorting algorithms, is
&lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt;", then that is &lt;em&gt;technically&lt;/em&gt; correct, but severely
misleading, because Toplogical Sort is also &lt;mathjax&gt;$O(n)$&lt;/mathjax&gt; which is a subset
of &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt;. Chances are whoever said it meant something false.&lt;/p&gt;
&lt;p&gt;If someone says &#x201C;In the worst case, any comparison based sorting
algorithm must make &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt; comparisons&#x201D; that is &lt;em&gt;not&lt;/em&gt; a
correct statement. Translated into English it becomes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&#x201C;In the worst case, any comparison based sorting algorithm must make
fewer than or equal to &lt;mathjax&gt;$M n \log (n)$&lt;/mathjax&gt; comparisons&#x201D;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which is not true: You can easily come up with a comparison based
sorting algorithm that makes more comparisons in the worst case.&lt;/p&gt;
&lt;p&gt;To be precise about these things we have other types of notation at
our disposal. Informally:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p/&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;mathjax&gt;$O()$&lt;/mathjax&gt;:&lt;/td&gt;&lt;td&gt;Less than or equal, disregarding constants&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;mathjax&gt;$\Omega()$&lt;/mathjax&gt;:&lt;/td&gt;&lt;td&gt;Greater than or equal, disregarding constants&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;mathjax&gt;$o()$&lt;/mathjax&gt;:&lt;/td&gt;&lt;td&gt;Stricly less than, disregarding constants&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;mathjax&gt;$\Theta()$&lt;/mathjax&gt;:&lt;/td&gt;&lt;td&gt;Equal to, disregarding constants&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/blockquote&gt;
&lt;p&gt;and &lt;a href="http://en.wikipedia.org/wiki/Big_O_notation#Family_of_Bachmann.E2.80.93Landau_notations" &gt;some more&lt;/a&gt;. The correct statement about lower bounds is this: &#x201C;In the worst case,
any comparison based sorting algorithm must make &lt;mathjax&gt;$\Omega(n \log n)$&lt;/mathjax&gt;
comparisons. In English that becomes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&#x201C;In the worst case, any comparison based sorting algorithm must make
at least &lt;mathjax&gt;$M n \log (n)$&lt;/mathjax&gt; comparisons&#x201D;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which is true. And a correct, non-misleading statement about
Topological Sort is that it is &lt;mathjax&gt;$\Theta(n)$&lt;/mathjax&gt;, because it has a lower
bound of &lt;mathjax&gt;$\Omega(n)$&lt;/mathjax&gt; and an upper bound of &lt;mathjax&gt;$O(n)$&lt;/mathjax&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 3:&lt;/b&gt; &#x201C;Big-O is a Statement About Time&#x201D;&lt;/p&gt;
&lt;p&gt;Big-O is used for making statements about functions. The functions can
measure time or space or cache misses or rabbits on an island or
anything or nothing. Big-O notation doesn&#x2019;t care.&lt;/p&gt;
&lt;p&gt;In fact, when used for algorithms, big-O is almost never about
time. It is about primitive operations.&lt;/p&gt;
&lt;p&gt;When someone says that the time complexity of MergeSort is &lt;mathjax&gt;$O(n \log
n)$&lt;/mathjax&gt;, they usually mean that the number of comparisons that MergeSort
makes is &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt;. That in itself doesn&#x2019;t tell us what the &lt;em&gt;time&lt;/em&gt;
complexity of any particular MergeSort might be because that would
depend how much time it takes to make a comparison. In other words,
the &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt; refers to &lt;em&gt;comparisons&lt;/em&gt; as the primitive operation.&lt;/p&gt;
&lt;p&gt;The important point here is that when big-O is applied to algorithms,
there is always an underlying model of computation. The claim that the
&lt;em&gt;time&lt;/em&gt; complexity of MergeSort is &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt;, is implicitly
referencing an model of computation where a comparison takes constant
time and everything else is free.&lt;/p&gt;
&lt;p&gt;Which is fine as far as it goes. It lets us compare MergeSort to other
comparison based sorts, such as QuickSort or ShellSort or BubbleSort,
and in many real situations, comparing two sort keys really does take
constant time.&lt;/p&gt;
&lt;p&gt;However, it doesn&#x2019;t allow us to compare MergeSort to RadixSort because
RadixSort is not comparison based. It simply doesn&#x2019;t ever make a
comparison between two keys, so its time complexity in the comparison
model is 0. The statement that RadixSort is &lt;mathjax&gt;$O(n)$&lt;/mathjax&gt; implicitly
references a model in which the keys can be lexicographically picked
apart in constant time. Which is also fine, because in many real
situations, you actually can do that.&lt;/p&gt;
&lt;p&gt;To compare RadixSort to MergeSort, we must first define a shared model
of computation. If we are sorting strings that are &lt;mathjax&gt;$k$&lt;/mathjax&gt; bytes long, we
might take &#x201C;read a byte&#x201D; as a primitive operation that takes constant
time with everything else being free.&lt;/p&gt;
&lt;p&gt;In this model, MergeSort makes &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt; string comparisons each
of which makes &lt;mathjax&gt;$O(k)$&lt;/mathjax&gt; byte comparisons, so the time complexity is
&lt;mathjax&gt;$O(k\cdot n \log n)$&lt;/mathjax&gt;. One common implementation of RadixSort will make
&lt;mathjax&gt;$k$&lt;/mathjax&gt; passes over the &lt;mathjax&gt;$n$&lt;/mathjax&gt; strings with each pass reading one byte, and
so has time complexity &lt;mathjax&gt;$O(n k)$&lt;/mathjax&gt;.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 4:&lt;/b&gt; Big-O Is About Worst Case&lt;/p&gt;
&lt;p&gt;Big-O is often used to make statements about functions that measure
the worst case behavior of an algorithm, but big-O notation doesn&#x2019;t
imply anything of the sort.&lt;/p&gt;
&lt;p&gt;If someone is talking about the randomized QuickSort and says that it
is &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt;, they presumably mean that its &lt;em&gt;expected running
time&lt;/em&gt; is &lt;mathjax&gt;$O(n \log n)$&lt;/mathjax&gt;. If they say that QuickSort is &lt;mathjax&gt;$O(n^2)$&lt;/mathjax&gt; they
are probably talking about its worst case complexity. Both statements
can be considered true depending on what type of running time the
functions involved are measuring.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 16 May 2013 05:14:35 GMT</pubDate>
      <title>Porter/Duff Compositing and Blend Modes</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=20</link>
      <guid>http://ssp.impulsetrain.com/2013-03-17_Porter_Duff_Compositing_and_Blend_Modes.html</guid>
      <description>&lt;p&gt;In the Porter/Duff compositing algebra, images are equipped with an
alpha channel that determines on a per-pixel basis whether the image
is there or not. When the alpha channel is 1, the image is fully
there, when it is 0, the image isn&#x2019;t there at all, and when it is in
between, the image is partially there. In other words, the alpha
channel describes the &lt;em&gt;shape&lt;/em&gt; of the image, it does not describe
opacity. The way to think of images with an alpha channel is as
irregularly shaped pieces of cardboard, not as colored glass. Consider
these two images:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/source.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/dest.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When we combine them, each pixel of the result can be divided into four regions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/diagram.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One region where only the source is present, one where only the
destination is present, one where both are present, and one where
neither is present.&lt;/p&gt;
&lt;p&gt;By deciding on what happens in each of the four regions, various
effects can be generated. For example, if the destination-only region
is treated as blank, the source-only region is filled with the source
color, and the &#x2018;both&#x2019; region is filled with the destination color like
this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/destatop-diagram.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The effect is as if the destination image is trimmed to match the
source image, and then held up in front of it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/destatop.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Porter/Duff operator that does this is called &#x201C;Dest Atop&#x201D;.&lt;/p&gt;
&lt;p&gt;There are twelve of these operators, each one characterized by its
behavior in the three regions: source, destination and both. The
&#x2018;neither&#x2019; region is always blank. The source and destination regions
can either be blank or filled with the source or destination colors
respectively.&lt;/p&gt;
&lt;p&gt;The formula for the operators is a linear combination of the contents
of the four regions, where the weights are the areas of each region:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$A_\text{src} \cdot [s] + A_\text{dest} \cdot [d] +  A_\text{both} \cdot [b]$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where &lt;mathjax&gt;$[s]$&lt;/mathjax&gt; is either 0 or the color of the source pixel, &lt;mathjax&gt;$[d]$&lt;/mathjax&gt;
either 0 or the color of the destination pixel, and &lt;mathjax&gt;$[b]$&lt;/mathjax&gt; is either
0, the color of the source pixel, or the color of the destination
pixel. With the alpha channel being interpreted as coverage, the areas
are given by these formulas:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$A_\text{src} = \alpha_\text{s} \cdot (1 - \alpha_\text{d})$&lt;/mathjax&gt;&lt;br/&gt;&lt;mathjax&gt;$A_\text{dst} = \alpha_\text{d} \cdot (1 - \alpha_\text{s})$&lt;/mathjax&gt;&lt;br/&gt;&lt;mathjax&gt;$A_\text{both} = \alpha_\text{s} \cdot \alpha_\text{d}$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The alpha channel of the result is computed in a similar way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$A_\text{src} \cdot [\text{as}] + A_\text{dest} \cdot [\text{ad}] + A_\text{both} \cdot [\text{ab}]$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where &lt;mathjax&gt;$[\text{as}]$&lt;/mathjax&gt; and &lt;mathjax&gt;$[\text{ad}]$&lt;/mathjax&gt; are either 0 or 1 depending
on whether the source and destination regions are present, and where
&lt;mathjax&gt;$[\text{ab}]$&lt;/mathjax&gt; is 0 when the &#x2018;both&#x2019; region is blank, and 1 otherwise.&lt;/p&gt;
&lt;p&gt;Here is a table of all the Porter/Duff operators:&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;&lt;td/&gt;
    &lt;td&gt;$[\text{s}]$&lt;/td&gt;
    &lt;td&gt;$[\text{d}]$&lt;/td&gt;
    &lt;td&gt;$[\text{b}]$&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Src&lt;/td&gt;
    &lt;td&gt;$s$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;s&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Atop&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$d$&lt;/td&gt;
    &lt;td&gt;s&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Over&lt;/td&gt;
    &lt;td&gt;$s$&lt;/td&gt;
    &lt;td&gt;$d$&lt;/td&gt;
    &lt;td&gt;s&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;In&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;s&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Out&lt;/td&gt;
    &lt;td&gt;$s$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Dest&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$d$&lt;/td&gt;
    &lt;td&gt;d&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestAtop&lt;/td&gt;
    &lt;td&gt;$s$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;d&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestOver&lt;/td&gt;
    &lt;td&gt;$s$&lt;/td&gt;
    &lt;td&gt;$d$&lt;/td&gt;
    &lt;td&gt;d&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestIn&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;d&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestOut&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$d$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Clear&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Xor&lt;/td&gt;
    &lt;td&gt;$s$&lt;/td&gt;
    &lt;td&gt;$d$&lt;/td&gt;
    &lt;td&gt;$0$&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;And here is how they look:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/table.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Despite being referred to as alpha blending and despite alpha often
being used to model opacity, in concept Porter/Duff is not a way to
blend the source and destination shapes. It is way to overlay, combine
and trim them as if they were pieces of cardboard. The only places
where source and destination pixels are actually &lt;em&gt;blended&lt;/em&gt; is where
the antialiased edges meet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blending&lt;/strong&gt;&lt;br/&gt;
Photoshop and the Gimp have a concept of layers which are images
stacked on top of each other. In Porter/Duff, stacking images on top
of each other is done with the &#x201C;Over&#x201D; operator, which is also what
Photoshop/Gimp use by default to composite layers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/over-diagram.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/over.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Conceptually, two pieces of cardboard are held up with one in front of
the other. Neither shape is trimmed, and in places where both are
present, only the top layer is visible.&lt;/p&gt;
&lt;p&gt;A layer in these programs also has an associated &lt;em&gt;Blend Mode&lt;/em&gt; which
can be used to modify what happens in places where both are
visible. For example, the &#x2018;Color Dodge&#x2019; blend mode computes a mix of
source and destination according to this formula:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$
\begin{equation*}
B(s,d)= 
\begin{cases} 0 &amp;amp; \text{if \(d=0\),}
\\
1 &amp;amp; \text{if \(d \ge (1 - s)\),}
\\
d / (1 - s) &amp;amp; \text{otherwise}
\end{cases}
\end{equation*}
$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The result is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/colordodge-diagram.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/colordodge-both.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unlike with the regular Over operator, in this case there is a
substantial chunk of the output where the result is actually a mix of
the source and destination.&lt;/p&gt;
&lt;p&gt;Layers in Photoshop and Gimp are not tailored to each other (except
for layer masks, which we will ignore here), so the compositing of the
layer stack is done with the source-only and destination-only region
set to source and destination respectively. However, there is nothing
in principle stopping us from setting the source-only and
destination-only regions to blank, but keeping the blend mode in the
&#x2018;both&#x2019; region, so that tailoring could be supported alongside
blending. For example, we could set the &#x2018;source&#x2019; region to blank, the
&#x2018;destination&#x2019; region to the destination color, and the &#x2018;both&#x2019; region
to ColorDodge:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/colordodge-dest-diagram.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/colordodge-dest.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are the four combinations that involve a ColorDodge blend mode:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/colordodge-none.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/colordodge-source.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/colordodge-dest.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&lt;img src="http://ssp.impulsetrain.com/colordodge-both.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this model the original twelve Porter/Duff operators can be viewed
as the results of three simple blend modes:&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;&lt;td&gt;Source:&lt;/td&gt;
    &lt;td&gt;$B(s, d) = s$&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Dest:&lt;/td&gt;
    &lt;td&gt;$B(s, d) = d$&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Zero:&lt;/td&gt;
    &lt;td&gt;$B(s, d) = 0$&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;In this generalization of Porter/Duff the blend mode is chosen from a
large set of formulas, and each formula gives rise to four new
compositing operators characterized by whether the source and
destination are blank or contain the corresponding pixel color.&lt;/p&gt;
&lt;p&gt;Here is a table of the operators that are generated by various blend
modes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/colordodge-table.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The general formula is still an area weighted average:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$A_\text{src} \cdot [s] + A_\text{dest} \cdot [d] + A_\text{both}\cdot B(s, d)$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where [s] and [d] are the source and destination colors respectively
or 0, but where &lt;mathjax&gt;$B(s, d)$&lt;/mathjax&gt; is no longer restricted to one of &lt;mathjax&gt;$0$&lt;/mathjax&gt;, &lt;mathjax&gt;$s$&lt;/mathjax&gt;,
and &lt;mathjax&gt;$d$&lt;/mathjax&gt;, but can instead be chosen from a large set of formulas.&lt;/p&gt;
&lt;p&gt;The output of the alpha channel is the same as before:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;mathjax&gt;$A_\text{src} \cdot [\text{as}] + A_\text{dest} \cdot [\text{ad}] +
A_\text{both} \cdot [\text{ab}]$&lt;/mathjax&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;except that [ab] is now determined by the blend mode. For the Zero
blend mode there is no coverage in the both region, so [ab] is 0; for
most others, there is full coverage, so [ab] is 1.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Sun, 17 Mar 2013 19:10:48 GMT</pubDate>
      <title>Porter/Duff Compositing and Blend Modes</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=19</link>
      <guid>http://ssp.impulsetrain.com/2013/03/17/porterduff-compositing-and-blend-modes/</guid>
      <description>&lt;p&gt;&lt;script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;![CDATA[&lt;![CDATA[
]]]]&gt;&lt;![CDATA[&gt;]]&gt;&lt;/script&gt;In the Porter/Duff compositing algebra, images are equipped with an alpha channel that determines on a per-pixel basis whether the image is there or not. When the alpha channel is 1, the image is fully there, when it is 0, the image isn&#x2019;t there at all, and when it is in between, the image is partially there. In other words, the alpha channel describes the &lt;em&gt;shape&lt;/em&gt; of the image, it does not describe opacity. The way to think of images with an alpha channel is as irregularly shaped pieces of cardboard, not as colored glass. Consider these two images:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/source.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/dest.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When we combine them, each pixel of the result can be divided into four regions:&lt;br/&gt;&lt;/p&gt;&lt;blockquote&gt;
  &lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/diagram.png"/&gt;&lt;/blockquote&gt;
&lt;p&gt;One region where only the source is present, one where only the destination is present, one where both are present, and one where neither is present.&lt;/p&gt;
&lt;p&gt;By deciding on what happens in each of the four regions, various effects can be generated. For example, if the destination-only region is treated as blank, the source-only region is filled with the source color, and the &#x2018;both&#x2019; region is filled with the destination color like this:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    &lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/destatop-diagram.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The effect is as if the destination image is trimmed to match the source image, and then held up in front of it:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    &lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/destatop.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Porter/Duff operator that does this is called &#x201C;Dest Atop&#x201D;.&lt;/p&gt;
&lt;p&gt;There are twelve of these operators, each one characterized by its behavior in the three regions: source, destination and both. The &#x2018;neither&#x2019; region is always blank. The source and destination regions can either be blank or filled with the source or destination colors respectively.&lt;/p&gt;
&lt;p&gt;The formula for the operators is a linear combination of the contents of the four regions, where the weights are the areas of each region:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;\(A_\text{src} \cdot [s] + A_\text{dest} \cdot [d] + A_\text{both} \cdot [b]\)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where \([s]\) is either 0 or the color of the source pixel, \([d]\) either 0 or the color of the destination pixel, and \([b]\) is either 0, the color of the source pixel, or the color of the destination pixel. With the alpha channel being interpreted as coverage, the areas are given by these formulas:&lt;br/&gt;&lt;/p&gt;&lt;blockquote&gt;
\(A_\text{src} = \alpha_\text{s} \cdot (1 &#x2013; \alpha_\text{d})\)&lt;br/&gt;
\(A_\text{dst} = \alpha_\text{d} \cdot (1 &#x2013; \alpha_\text{s})\)&lt;br/&gt;
\(A_\text{both} = \alpha_\text{s} \cdot \alpha_\text{d}\)
&lt;/blockquote&gt;
&lt;p&gt;The alpha channel of the result is computed in a similar way:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
\(A_\text{src} \cdot [\text{as}] + A_\text{dest} \cdot [\text{ad}] + A_\text{both} \cdot [\text{ab}]\)
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where \([\text{as}]\) and \([\text{ad}]\) are either 0 or 1 depending on whether the source and destination regions are present, and where \([\text{ab}]\) is 0 when the &#x2018;both&#x2019; region is blank, and 1 otherwise.&lt;/p&gt;
&lt;p&gt;Here is a table of all the Porter/Duff operators:&lt;br/&gt;&lt;/p&gt;&lt;table&gt;
  &lt;tr&gt;&lt;td/&gt;
&lt;td&gt;\([\text{s}]\)&lt;/td&gt;
&lt;td&gt;\([\text{d}]\)&lt;/td&gt;
&lt;td&gt;\([\text{b}]\)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Src&lt;/td&gt;
&lt;td&gt;\(s\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Atop&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(d\)&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Over&lt;/td&gt;
&lt;td&gt;\(s\)&lt;/td&gt;
&lt;td&gt;\(d\)&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;In&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Out&lt;/td&gt;
&lt;td&gt;\(s\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Dest&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(d\)&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestAtop&lt;/td&gt;
&lt;td&gt;\(s\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestOver&lt;/td&gt;
&lt;td&gt;\(s\)&lt;/td&gt;
&lt;td&gt;\(d\)&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestIn&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;DestOut&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(d\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Clear&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Xor&lt;/td&gt;
&lt;td&gt;\(s\)&lt;/td&gt;
&lt;td&gt;\(d\)&lt;/td&gt;
&lt;td&gt;\(0\)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;And here is how they look:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    &lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/table.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Despite being referred to as alpha blending and despite alpha often being used to model opacity, in concept Porter/Duff is not a way to blend the source and destination shapes. It is way to overlay, combine and trim them as if they were pieces of cardboard. The only places where source and destination pixels are actually &lt;em&gt;blended&lt;/em&gt; is where the antialiased edges meet.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Blending&lt;/b&gt;&lt;br/&gt;
Photoshop and the Gimp have a concept of layers which are images stacked on top of each other. In Porter/Duff, stacking images on top of each other is done with the &#x201C;Over&#x201D; operator, which is also what Photoshop/Gimp use by default to composite layers:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/over-diagram.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/over.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Conceptually, two pieces of cardboard are held up with one in front of the other. Neither shape is trimmed, and in places where both are present, only the top layer is visible.&lt;/p&gt;
&lt;p&gt;A layer in these programs also has an associated &lt;em&gt;Blend Mode&lt;/em&gt; which can be used to modify what happens in places where both are visible. For example, the &#x2018;Color Dodge&#x2019; blend mode computes a mix of source and destination according to this formula:&lt;br/&gt;&lt;/p&gt;&lt;blockquote&gt;
\(\begin{equation*}&lt;br/&gt;
B(s,d)=&lt;br/&gt;
\begin{cases} 0 &amp;amp; \text{if \(d=0\),}&lt;br/&gt;
\\&lt;br/&gt;
1 &amp;amp; \text{if \(d \ge (1 &#x2013; s)\),}&lt;br/&gt;
\\&lt;br/&gt;
d / (1 &#x2013; s) &amp;amp; \text{otherwise}&lt;br/&gt;
\end{cases}&lt;br/&gt;
\end{equation*}\)
&lt;/blockquote&gt;
&lt;p&gt;The result is this:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-diagram.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-both.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unlike with the regular Over operator, in this case there is a substantial chunk of the output where the result is actually a mix of the source and destination.&lt;/p&gt;
&lt;p&gt;Layers in Photoshop and Gimp are not tailored to each other (except for layer masks, which we will ignore here), so the compositing of the layer stack is done with the source-only and destination-only region set to source and destination respectively. However, there is nothing in principle stopping us from setting the source-only and destination-only regions to blank, but keeping the blend mode in the &#x2018;both&#x2019; region, so that tailoring could be supported alongside blending. For example, we could set the &#x2018;source&#x2019; region to blank, the &#x2018;destination&#x2019; region to the destination color, and the &#x2018;both&#x2019; region to ColorDodge:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-dest-diagram.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-dest.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are the four combinations that involve a ColorDodge blend mode:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-none.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-source.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-dest.png"/&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-both.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this model the original twelve Porter/Duff operators can be viewed as the results of three simple blend modes:&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;&lt;td&gt;Source:&lt;/td&gt;
&lt;td&gt;\(B(s, d) = s\)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Dest:&lt;/td&gt;
&lt;td&gt;\(B(s, d) = d\)&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;Zero:&lt;/td&gt;
&lt;td&gt;\(B(s, d) = 0\)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;In this generalization of Porter/Duff the blend mode is chosen from a large set of formulas, and each formula gives rise to four new compositing operators characterized by whether the source and destination are blank or contain the corresponding pixel color.&lt;/p&gt;
&lt;p&gt;Here is a table of the operators that are generated by various blend modes:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
    &lt;img src="http://ssp.impulsetrain.com/wp-content/uploads/2013/03/colordodge-table.png"/&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The general formula is still an area weighted average:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;\(A_\text{src} \cdot [s] + A_\text{dest} \cdot [d] + A_\text{both}\cdot B(s, d)\)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where [s] and [d] are the source and destination colors respectively or 0, but where \(B(s, d)\) is no longer restricted to one of \(0\), \(s\), and \(d\), but can instead be chosen from a large set of formulas.&lt;/p&gt;
&lt;p&gt;The output of the alpha channel is the same as before:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;\(A_\text{src} \cdot [\text{as}] + A_\text{dest} \cdot [\text{ad}] + A_\text{both} \cdot [\text{ab}]\)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;except that [ab] is now determined by the blend mode. For the Zero blend mode there is no coverage in the both region, so [ab] is 0; for most others, there is full coverage, so [ab] is 1.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 15 Oct 2012 10:24:51 GMT</pubDate>
      <title>Big-O Misconceptions</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=18</link>
      <guid>http://ssp.impulsetrain.com/2012/10/15/big-o-misconceptions/</guid>
      <description>&lt;p&gt;&lt;script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"&gt;&lt;![CDATA[&lt;![CDATA[
]]]]&gt;&lt;![CDATA[&gt;]]&gt;&lt;/script&gt;In computer science and sometimes mathematics, big-O notation is used&lt;br/&gt;
to talk about how quickly a function grows while disregarding multiplicative and additive constants. When classifying algorithms, big-O notation is useful because it lets us abstract away the differences between real computers as just multiplicative and additive constants.&lt;/p&gt;
&lt;p&gt;Big-O is not a difficult concept at all, but it seems to be common even for people who should know better to misunderstand some aspects of it. The following is a list of misconceptions that I have seen in the wild.&lt;/p&gt;
&lt;p&gt;But first a definition: We write $$f(n) = O(g(n))$$ when \(f(n) \le M g(n)\) for sufficiently large \(n\), for some positive constant \(M\).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 1:&lt;/b&gt; &#x201C;The Equals Sign Means Equality&#x201D;&lt;/p&gt;
&lt;p&gt;The equals sign in $$f = O(g(n))$$ is a widespread travestry. If you take it at face value, you can deduce that since \(5 n\) and \(3 n\) are both equal to \(O(n)\), then \(3 n\) must be equal to \(5 n\) and so \(3 = 5\).&lt;/p&gt;
&lt;p&gt;The expression \(f = O(g(n))\) doesn&#x2019;t type check. The left-hand-side is a function, the right-hand-side is a &#x2026; what, exactly? There is no help to be found in the definition. It just says &#x201C;we write&#x201D; without concerning itself with the fact that what &#x201C;we write&#x201D; is total nonsense.&lt;/p&gt;
&lt;p&gt;The way to interpret the right-hand side is as a &lt;em&gt;set&lt;/em&gt; of functions: $$O(f) = \{ g \mid g(n) \le M f(n) \text{ for some \(M &amp;gt; 0\) for large \(n\)}\}.$$ With this definition, the world makes sense again: If \(f(n) = 3 n\) and \(g(n) = 5 n\), then \(f \in O(n)\) and \(g \in O(n)\), but there is no equality involved so we can&#x2019;t make bogus deductions like \(3=5\). We can however make the correct observation that \(O(n) \subseteq O(n \log n)\subseteq O(n^2) \subseteq O(n^3)\), something that would be difficult to express with the equals sign.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 2:&lt;/b&gt; &#x201C;Informally, Big-O Means &#x2018;Approximately Equal&#x2019;&#x201D;&lt;/p&gt;
&lt;p&gt;If an algorithm takes \(5 n^2\) seconds to complete, that algorithm is \(O(n^2)\) because for the constant \(M=7\) and sufficiently large \(n\), \(5 n^2 \le 7 n^2\). But an algorithm that runs in constant time, say 3 seconds, is also \(O(n^2)\) because for sufficiently large \(n\), \(3 \le n^2\).&lt;/p&gt;
&lt;p&gt;So informally, big-O means &lt;em&gt;approximately less than or equal&lt;/em&gt;, not &lt;em&gt;approximately equal&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If someone says &#x201C;Topological Sort, like other sorting algorithms, is O(n log n)&#x201D;, then that is &lt;em&gt;technically&lt;/em&gt; correct, but severely misleading, because Toplogical Sort is also \(O(n)\) which is a subset of \(O(n \log n)\). Chances are whoever said it meant something false.&lt;/p&gt;
&lt;p&gt;If someone says &#x201C;In the worst case, any comparison based sorting algorithm must make \(O(n \log n)\) comparisons&#x201D; that is &lt;em&gt;not&lt;/em&gt; a correct statement. Translated into English it becomes:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
&#x201C;In the worst case, any comparison based sorting algorithm must make fewer than or equal to \(M n  \log (n)\) comparisons&#x201D;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which is not true: You can easily come up with a comparison based sorting algorithm that makes more comparisons in the worst case.&lt;/p&gt;
&lt;p&gt;To be precise about these things we have other types of notation at our disposal. Informally:&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;&lt;td&gt;\(O()\):&lt;/td&gt;
&lt;td&gt;Less than or equal, disregarding constants&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;\(\Omega()\):&lt;/td&gt;
&lt;td&gt;Greater than or equal, disregarding constants&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;\(o()\):&lt;/td&gt;
&lt;td&gt;Stricly less than, disregarding constants&lt;/td&gt;
&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;\(\Theta()\):&lt;/td&gt;
&lt;td&gt;Equal to, disregarding constants&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;and &lt;a href="http://en.wikipedia.org/wiki/Big_O_notation#Family_of_Bachmann.E2.80.93Landau_notations" &gt;some more&lt;/a&gt;. The correct statement about lower bounds is this: &#x201C;In the worst case, any comparison based sorting algorithm must make \(\Omega(n \log n)\) comparisons. In English that becomes:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;
&#x201C;In the worst case, any comparison based sorting algorithm must make at least \(M n \log (n)\) comparisons&#x201D;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;which is true. And a correct, non-misleading statement about Topological Sort is that it is \(\Theta(n)\), because it has a lower bound of \(\Omega(n)\) and an upper bound of \(O(n)\).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 3:&lt;/b&gt; &#x201C;Big-O is a Statement About Time&#x201D;&lt;/p&gt;
&lt;p&gt;Big-O is used for making statements about functions. The functions can measure time or space or cache misses or rabbits on an island or anything or nothing. Big-O notation doesn&#x2019;t care.&lt;/p&gt;
&lt;p&gt;In fact, when used for algorithms, big-O is almost never about time. It is about primitive operations.&lt;/p&gt;
&lt;p&gt;When someone says that the time complexity of MergeSort is \(O(n \log n)\), they usually mean that the number of comparisons that MergeSort makes is \(O(n \log n)\). That in itself doesn&#x2019;t tell us what the &lt;em&gt;time&lt;/em&gt; complexity of any particular MergeSort might be because that would depend how much time it takes to make a comparison. In other words, the \(O(n \log n)\) refers to &lt;em&gt;comparisons&lt;/em&gt; as the primitive operation.&lt;/p&gt;
&lt;p&gt;The important point here is that when big-O is applied to algorithms, there is always an underlying model of computation. The claim that the &lt;em&gt;time&lt;/em&gt; complexity of MergeSort is \(O(n \log n)\), is implicitly referencing an model of computation where a comparison takes constant time and everything else is free.&lt;/p&gt;
&lt;p&gt;Which is fine as far as it goes. It lets us compare MergeSort to other comparison based sorts, such as QuickSort or ShellSort or BubbleSort, and in many real situations, comparing two sort keys really does take constant time.&lt;/p&gt;
&lt;p&gt;However, it doesn&#x2019;t allow us to compare MergeSort to RadixSort because RadixSort is not comparison based. It simply doesn&#x2019;t ever make a comparison between two keys, so its time complexity in the comparison model is 0. The statement that RadixSort is \(O(n)\) implicitly references a model in which the keys can be lexicographically picked apart in constant time. Which is also fine, because in many real situations, you actually can do that.&lt;/p&gt;
&lt;p&gt;To compare RadixSort to MergeSort, we must first define a shared model of computation. If we are sorting strings that are \(k\) bytes long, we might take &#x201C;read a byte&#x201D; as a primitive operation that takes constant time with everything else being free.&lt;/p&gt;
&lt;p&gt;In this model, MergeSort makes \(O(n \log n)\) string comparisons each of which makes \(O(k)\) byte comparisons, so the time complexity is \(O(k n \log n)\). One common implementation of RadixSort will make \(k\) passes over the \(n\) strings with each pass reading one byte, and so has time complexity \(O(n k) \).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Misconception 4:&lt;/b&gt; Big-O Is About Worst Case&lt;/p&gt;
&lt;p&gt;Big-O is often used to make statements about functions that measure the worst case behavior of an algorithm, but big-O notation doesn&#x2019;t imply anything of the sort.&lt;/p&gt;
&lt;p&gt;If someone is talking about the randomized QuickSort and says that it is \(O(n \log n)\), they presumably mean that its &lt;em&gt;expected running time&lt;/em&gt; is \(O(n \log n)\). If they say that QuickSort is \(O(n^2)\) they are probably&lt;br/&gt;
talking about its worst case complexity. Both statements can be considered true depending on what type of running time the functions involved are measuring.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Sat, 8 Sep 2012 22:09:27 GMT</pubDate>
      <title>Sysprof 1.2.0</title>
      <link>http://www.advogato.org/person/ssp/diary.html?start=17</link>
      <guid>http://ssp.impulsetrain.com/2012/09/08/sysprof-1-2-0/</guid>
      <description>&lt;p&gt;A &lt;a href="https://lkml.org/lkml/2012/9/8/143" &gt;new stable release&lt;/a&gt; of &lt;a href="http://sysprof.com/" &gt;Sysprof&lt;/a&gt; is now available. Download &lt;a href="http://sysprof.com/sysprof-1.2.0.tar.gz" &gt;version 1.2.0&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
