Sunday, March 21, 2010

Embedding LaTeX in Blogger take 2

After further consideration on Embedding LaTeX in Blogger I have the following concerns in using jsLaTeX.

  • LaTeX images not rendered in RSS readers

  • Stability of all the components over (a long) time

jsMath improves on point 2, but looks way too hard to host on Blogger. So I am falling back to using images generated by the CodeCogs online equation editor hosted on Picasa, which is where Blogger uploads images. I put the LaTeX source in the img alt attribute.

Blogger resizing images
After adding a few equations through the standard Blogger mechanism, I noticed that they weren't as clear when previewing. The following two equations are the same image hosted on Picasa, but embedded with different src urls.



This is using the Blogger generated url in the image tag and has size 400 x 285 pixels.



This is using the Picasa generated url and has the original size of 415 x 296 pixels.

Notice how the first image is both smaller and blurry. It seems that Blogger is automatically resizing it. Unfortunately this means a little more work for each equation as it requires generating the link in Picasa and replacing the Blogger generated image tag.

Computing variance

Given a list of n numbers x_1,x_2,...,x_n, the variance is defined as

\frac{1}{n}\sum_{i=1}^n{\left(x_i - \bar{x}\right)^2}\quad\quad\quad\text{(1)}

where \bar{x} is the arithmetic mean.

\bar{x} = \frac{1}{n}\sum_{i=1}^n{x_i}

Expression 1 stated in words is the average squared difference of each data point from the mean. Implemented as an algorithm, this requires two passes over the data set. The first to calculate the mean and the second to sum the squared differences.

Let's derive the more commonly used expression for variance.

\begin{align*}<br />\frac{1}{n}\sum_{i=1}^n{\left(x_i - \bar{x}\right)^2} & =  \frac{1}{n}\sum_{i=1}^n{\left({x_i}^2 - 2x_i\bar{x} + \bar{x}^2\right)} \\<br />& = \frac{1}{n}\left(\sum_{i=1}^n{x_i}^2 - 2\bar{x}\sum_{i=1}^n{x_i} + n\bar{x}^2\right) \\<br />& = \frac{1}{n}\sum_{i=1}^n{x_i}^2 - 2\bar{x}^2 + \bar{x}^2 \\<br />& = \frac{1}{n}\sum_{i=1}^n{x_i}^2 - \bar{x}^2 \\<br />& = \frac{1}{n}\sum_{i=1}^n{x_i}^2 - \left(\frac{1}{n}\sum_{i=1}^n{x_i}\right)^2 && \text{(2)}<br />\end{align*}

This only requires a single pass over the data set, computing the incremental sum of the values and the incremental sum of their squares. However, if the terms in the subtraction are large and close enough, catastrophic cancellation can occur. Essentially the precision of the floating point representation is exceeded, yielding unacceptable results. See Algorithms for calculating variance and Theoretical explanation for numerical results for examples (they are calculating the sample variance which is slightly different). More detailed information on catastrophic cancellation can be found in What Every Computer Scientist Should Know About Floating Point Arithmetic (1991).

A more numerically stable (but computationally expensive) single pass algorithm was published by Knuth in The Art of Computer Programming, volume 2. Define \bar{x}_n and s_n as the mean and sum of squared differences of the the first n values respectively.

\begin{align*}<br />s_0 & = 0\\<br />\\<br />s_{n+1} & = \sum_{i=1}^{n+1}\left(x_i-\bar{x}_{n+1}\right)^2\\<br />& = s_n + \left(x_{n+1}-\bar{x}_n\right)\left(x_{n+1}-\bar{x}_{n+1}\right)\quad\quad\quad(3)<br />\end{align*}

For m > 0 values, the variance is then \frac{s_m}{m}.

Derivation of Equation 3
This is really just a more verbose version of one-pass algorithm to compute sample variance. First up is the running mean.

\begin{align*}<br />\bar{x}_0 & = 0\\<br />\\<br />\bar{x}_{n+1} & = \frac{n\bar{x}_n + x_{n+1}}{n+1}\\<br />& = \frac{\left(n+1\right)\bar{x}_n-\bar{x}_n+x_{n+1}}{n+1}\\<br />& = \bar{x}_n + \frac{x_{n+1}-\bar{x}_n}{n+1} && \quad &&& (4)\\<br />\end{align*}

If you think of the mean visually i.e. a horizontal line through the data on a scatter plot, then it is intuitive that the sum of the distances between each point and the mean is zero.

\sum_{i=1}^n\left(x_i-\bar{x}_n\right) & = \sum_{i=1}^nx_i-n\left(\frac{1}{n}\sum_{i=1}^nx_i\right)=0\quad\quad\quad(5)

Now define \gamma as the difference of consecutive incremental means, along with a few useful variations.

\begin{align*}<br />\gamma & = \bar{x}_{n+1} - \bar{x}_n && \quad &&& (6)\\<br />\\<br />\gamma & = \bar{x}_n + \frac{x_{n+1}-\bar{x}_n}{n+1} - \bar{x}_n && &&& \text{by (4)}\\<br />\gamma & = \frac{x_{n+1}-\bar{x}_n}{n+1} \\<br />\left(n+1\right)\gamma & = x_{n+1}-\bar{x}_n && &&& (7)\\<br />\\<br />x_{n+1}-\bar{x}_{n+1} & = x_{n+1}-\bar{x}_n+\bar{x}_n-\bar{x}_{n+1} \\<br />& = \left(n+1\right)\gamma-\gamma && &&& \text{by (7, 6)} \\<br />& = n\gamma && &&& (8)\\<br />\end{align*}

The pieces are now all in place to derive equation 3.

\begin{align*}<br />s_{n+1} & = \sum_{i=1}^{n+1}\left(x_i-\bar{x}_{n+1}\right)^2\\<br />& = \sum_{i=1}^{n}\left(x_i-\bar{x}_{n+1}\right)^2 + \left(x_{n+1}-\bar{x}_{n+1}\right)^2\\<br />& = \sum_{i=1}^{n}\left(x_i-\bar{x}_n+\bar{x}_n-\bar{x}_{n+1}\right)^2 + \left(n\gamma\right)^2 && \quad &&& \text{by (8)}\\<br />& = \sum_{i=1}^{n}\left(\left(x_i-\bar{x}_n\right)-\gamma\right)^2+n^2\gamma^2 && &&& \text{by (6)}\\<br />& = \sum_{i=1}^{n}\left(x_i-\bar{x}_n\right)^2 -2\gamma\sum_{i=1}^{n}\left(x_i-\bar{x}_n\right)+n\gamma^2+n^2\gamma^2\\<br />& = s_n-0+n\gamma^2\left(1+n\right) && &&& \text{by (5)}\\<br />& = s_n+\left(x_{n+1}-\bar{x}_n\right)n\gamma && &&& \text{by (7)}\\<br />& = s_n+\left(x_{n+1}-\bar{x}_n\right)\left(x_{n+1}-\bar{x}_{n+1}\right) && &&& \text{by (8)}<br />\end{align*}

Friday, March 12, 2010

Embeding LaTeX in Blogger

The goal is to include mathematical equations in blog posts. My plan was to create images from the output of MacTeX. Apart from being painfully slow to crop and upload with multiple distinct equations, the LaTeX source would not be contained in the post.

Embedding LaTeX in HTML led me to jsLaTeX. Option 4 from Solutions for JavaScript Hosting in Blogger solved the Blogger hosting issue. After some CSS shenanigans we have Bayes rule right here, right now.

\mathbb{P}(B_j|A) = \frac{\mathbb{P}(A|B_j)\mathbb{P}(B_j)}{\sum_{i=1}^n\mathbb{P}(A|B_i)\mathbb{P}(B_i)}

It is easier to write simple equations in the CodeCogs online equation editor first as Blogger preview doesn't seem to execute the JavaScript to render them.

Edit 23/03/2010: No longer using jsLaTeX, see Embedding LaTeX in Blogger take 2.

Friday, February 19, 2010

F# examples talk at BFG

Earlier this week I gave a short talk at the Brisbane Functional Group on F#. The idea was to give an introductory feel for the language by way of some simple examples. The talk was intended to be short so I assumed knowledge of previously discussed idioms such as tuples and curried type signatures.

I took the examples (with permission :-) from the environmental sensing project I work on at MQUTeR. This post is intended as a reference for those who attended rather than a self-contained introduction to F#.

  1. The uncurry function was first up.
    let uncurry f (x,y) = f x y
    We talked about the syntax of function definition, tuples and type inference in Visual Studio. We inserted the function into F# Interactive (the REPL available in Visual Studio) by highlighting it and pressing ALT-Enter. The F# Interactive transcript went something like:
    val uncurry : ('a -> 'b -> 'c) -> 'a * 'b -> 'c

    > 1 + 2;;
    val it : int = 3

    > uncurry (+) (1,2);;
    val it : int = 3

    > (+) 1 2;;
    val it : int = 3
    This lead to a discussion on operators and infix/prefix notation. The post F# Option orElse getOrElse functions should cover that.

  2. Next was the |> operator, which has type signature 'a -> ('a -> 'b) -> 'b.
    // Haskell catMaybes
    let catOptions xs = Seq.filter Option.isSome xs |> Seq.map Option.get

    let euclidianDist (x1, y1) (x2, y2) = (x1 - x2) ** 2.0 + (y1 - y2) ** 2.0 |> sqrt

    let spt' t a =
    let m = Math.Matrix.ofArray2D a
    allPeaks t m |> removeSmall |> dilate t m |> Math.Matrix.toArray2D

    // type signatures
    // allPeaks : float -> matrix -> matrix
    // removeSmall : matrix -> matrix
    // dilate : float -> matrix -> matrix -> matrix
    // spt' : float -> float [,] -> float [,]
    We briefly compared |> with the Haskell $ function, which has the type signature (a -> b) -> a -> b.

  3. A quick look at type annotations, pattern matching and Haskell like guards. The example is an implementation of the MATLAB smooth function, which calculates a moving average. We didn't dwell on the entire function, just the relevant parts.
    (* 
    yy = smooth(y,span) sets the span of the moving average to span. span must be odd.

    If span = 5 then the first few elements of yy are given by:
    yy(1) = y(1)
    yy(2) = (y(1) + y(2) + y(3))/3
    yy(3) = (y(1) + y(2) + y(3) + y(4) + y(5))/5
    yy(4) = (y(2) + y(3) + y(4) + y(5) + y(6))/5
    ...
    *)
    let smooth s (a:float []) =
    let n = (s - 1) / 2
    let f i _ =
    let (b, l) = match i with
    | _ when i < n -> (0, i*2+1)
    | _ when i + n < a.GetLength(0) -> (i-n, s)
    | _ -> (i-(a.GetLength(0)-1-i), (a.GetLength(0)-1-i)*2+1)
    Array.sum (Array.sub a b l) / (float l) // TODO try Array.average here
    Array.mapi f a

  4. Records are a common kind of data type. The labels are not automatically available as functions like they are in Haskell.
    type 'a Rectangle = {Left:'a; Top:'a; Right:'a; Bottom:'a; Width:'a; Height:'a;}

    let inline cornersToRect l r t b = {Left=l; Top=t; Right=r; Bottom=b; Width=r-l; Height=t-b;}
    let inline lengthsToRect l t w h = {Left=l; Top=t; Right=l+w-1; Bottom=t+h-1; Width=w; Height=h;}
    let fcornersToRect (l:float) r t b = cornersToRect l r t b // for C#
    let left r = r.Left
    let right r = r.Right
    let top r = r.Top
    let bottom r = r.Bottom
    let bottomLeft r = (r.Left, r.Bottom)
    let width r = r.Width
    let height r = r.Height
    let inline area r = r.Width * r.Height
    The F# overload-o-phone covers our discussion on arithmetic operators. The inline keyword is mentioned in the comments.

  5. Finally we looked at available API documentation. I find that I generally skim API documentation by first looking at function type signatures. The F# PowerPack is a useful library developed by the F# team and the format of the documentation supports my approach.

    The F# API documentation was previously in this format. It has now been moved to MSDN and the list of function type signatures is not presented for each module, rendering it almost useless.
Along the way there were a few comments about F# being strictly evaluated and having no effect tracking system, no higher-order parametric polymorphism and no type classes.

Thanks to everyone that participated in the discussion and I hope the talk was interesting.

Friday, February 12, 2010

QOTD

The role of the proof for mathematics is similar to that for orthography or even calligraphy for poetry. A person, who had not mastered the art of the proofs in high school, is as a rule unable to distinguish correct reasoning from that which is misleading. Such people can be easily manipulated by the irresponsible politicians.

-- V.I. Arnold

From: The antiscientifical revolution and mathematics

Thursday, February 4, 2010

Pair Programming again

I saw a local bank advertising a position to promote so called "sustainable software development" practices. These included Pair Programming, TDD, BDD and 100% code coverage.

I have written about Pair Programming before, but it needs re-iterating.

  • The value of pair programming is not constant - it is a function of the problem, people and technologies at hand.

  • If the problem at hand is not new or not complex the value is often significantly reduced.

  • On common information systems / web projects (such as at this company) the problem at hand is often neither new nor complex.

  • Therefore, if there is a project rule stating that all production code is to be paired on, the business value of the project will immediately be sub-optimal.
This is not rocket science. Consider a couple of competent developers pairing on the usual crud/plumbing code that makes up such a large proportion of these kinds of apps. What value is the second person really adding here vs doing something else?

Anecdotally, with skilled developers of reasonable talent and discipline, the pair programming time on these types of projects doesn't need to be above 50%.

Monday, January 11, 2010

Twitter error



One of the many times twitter has barfed on me.