Tuesday, May 13, 2008

The most useful function we never learned at school

In school math we learned all about sin() and cos() and tan() and log() and a few other trigonometric and special functions. But one of the most useful functions I have ever come across never got taught and perhaps it should.

I have programmed variants of this function in just about every language I have ever programmed in, and I use it all over the place. And it is a function that has applications in real life in just about every field.

The function is just a linear map. If we have something that takes one value at some time and a different value at another time, and the value is changing in the simplest possible way between the two times (ie linearly), what is the value at some intermediate or later time.

In general, if we have a linear function of a variable x with value y1 when x=x1 and value y2 when x= x2, what is the value in general?

A long time ago (ie FORTAN days), I would write a function

y = li(x, x1, y1, x2, y2)

with five parameters and then call this whenever I wanted to map from world to screen coordinates or any other application. Now very often I want to have the same linear map available for many many calls (like in doing computer graphics), so I would end up writing another function

y = li1(x, a, b)

where I could precompute a and b. Or even keeping a and b as global variables, setting them and just being able to call a function with a single parameter.

Now fast forward to Python. I figured out early on I could just do this

def li(x1,y1, x2,y2):
b = (y2-y1)/(x2-x1)
a = y1 - x1*b
def f(x):
return a+b*x
return f


so then I could create a function taking only a single x value and evaluate that to my hearts content:

>>> f = li(0., 3., 1., 2.)
>>> f(4)
-1.0
>>> f(2)
1.0
>>> f(1)
2.0
>>> f(0)
3.0
>>>


or if I wanted a single call

y = li(2., 2., 3., 5.)(4.5)



Apparently I had discovered closures, which turn out to be a good thing in functional languages and computer science. My li() function (LinearInterpolate) sets up a closure, encapsulating the parameters, and allows the actual function to be called while keeping these values (in this case the precomputed intercept and slope, for those who did traditional cartesian geometry at high school)

Anyway, this linear map function turns up all over the place in coding and is such a useful animal that it should be taught in school. Trigonometry has its uses but straight linear mappings are probably much more common in real life! If you bank balance is $335.47 in January and $221.38 in March, and you don't change your spending or earning habits, what will it be in September?


>>> lin(1, 335.47, 3, 221.38) (9)
-120.89
>>>


So it is likely that you will change your spending habits (unless you have arranged an overdraft)

No comments: