I used to watch the television show "MASH" years ago. They would refer to quick procedures for patient stabilization as "meatball surgery." I recently encountered some "meatball math" as part of my engineering job. I call it "meatball" because the "patient", a recalcitrant laser, had to be fixed quickly and rough approximations were totally acceptable. This application was a nice application of Mathcad and the implementation of the approximation in C will soon be going out in one our software loads.
We use AVR processors from Atmel to perform simple controller functions. I like these processors so much that I have an AVR development system at home (you never know when you might want to cookup some controller code). In one of our products, we need to estimate the threshold current for a laser at a given temperature. It turns out that Equation 1 [Keiser] does a fair job of modeling the temperature variation of the threshold current.
Equation 1 requires the computation of an exponential function. Unfortunately, a library version of the exponential function requires lots of memory space and my available AVR memory space is very small. However, it turns out that I do not need tremendous accuracy in this application – ±2% would be fine. I started to think in terms of a piecewise linear approximation. Let's take a look at what this approximation involves.
We begin with some simple algorithm requirements:
- We need to compute the exponential function over an input range from 0 to 1.5
- The exponential function must be accurate within 2%.
- The routine must occupy much less memory than the accurate exponential library routine.
As always, I began my work by seeing if anyone else has already solved my problem. My first search turned up an article on a bifurcated linear approximation to the exponential function over the input range 0 to 1.
Figure 1 shows a plot of the bifurcated approximation. This equation meets my accuracy requirement, but it is not designed for my input range from 0 to 1.5. Let's use Mathcad to fix this.
I needed to get this approximation out quickly, so I decided to augment the range setup of Equation 1 (0 to 0.5, and 0.5 to 1) with a third range (1.0 to 1.5).
Figure 2 shows the form of my linear function and my error function, which I will minimize. I am using the "minimax" optimality criterion for my approximation.
We can use solver to find the optimal solution. Figure 3 shows my solution setup. Note that I randomly chose the starting values. I ended up trying various random starting values to come to my final choice of coefficients.
Note how I am also enforcing a continuity requirement at the end points of my ranges. The bifurcated solution did not enforce this criterion and their error function was not smooth. Figure 4 shows the results of my Mathcad work.
This solution was simple and took very little memory. Note that we ended up implementing it in fixed point math, which is probably worth another blog post.
The equation shown in Figure 4 solved my problem. This was a good example of a "quick and dirty" solution to a common engineering dilemma -- an accurate solution is too big or expensive and you need to find an approach that is good enough. That is exactly what was done here.