CMP EMBEDDED.COM

Login | Register     Welcome Guest RFID World  Logic NVM  TeardownTV
 

Vectors--the last word



Embedded Systems Design

Engineers and mathematicians have been encountering the zero vector for as long as vectors themselves have existed. Here's how to handle it when writing a computer program.

When I uploaded the code for my last column, I included all the vector functions in class Vector, but I didn't discuss them all. My first order of business this time is to cover those functions we haven't discussed yet.

The key function is the function Norm( ), which computes the scalar length of a vector. For a vector of length N, the norm is defined to be:

(1)

(Here I'm using the mathematical index convention, where the first element is element 1.) The norm of a vector is the same as its absolute value, often written:

A related function, Unitize( ), takes a vector of any length and returns one whose norm is equal to 1. This kind of vector is called, unsurprisingly, a unit vector, and a need for such a vector pops up quite often. The unit vector has the definition:

(2)

This usually works. Unfortunately, it doesn't, always, and I'm sure you can see why. If every element of r is identically zero, so will be its norm. The operation will fail, and fail catastrophically, with a divide-by-zero exception.

Engineers and mathematicians have been encountering this problem for as long as vectors themselves have existed. When you're doing analysis by hand, it's easy enough to recognize the situation and deal with it as a special case. But if you're doing it in a computer program, you absolutely must tell the computer what you expect it to do in the exceptional case. In real-time software, a crash and burn response is not an option.

The naïve approach is to simply implement Equation 2 verbatim and hope for the best. After all (one might argue), how likely is it that we will actually encounter a truly zero-length vector, in practice? Answer: very likely indeed, if that's the value the vector is initialized to (that is, in our default constructor). A friend of mine was once given the task of modifying some existing code--a production-quality product that had been running and heavily used for years. No one had ever encountered a problem. It constructed a unit vector based on the difference of two other vectors. For his test case, he chose the simplest one he could think of, which was to use the same vector in the difference operation. That gave him a zero vector, and you know the rest.

In real-time software, we must test for the norm before we divide, and do something special for that case.

But what should the special thing be? Some folks choose to return a zero vector for the exception null case, but that choice presents its own problems.

When you use a library function, the description of the function represents some kind of contract between ths software and the user. Give the software an input meeting certain criteria A, and it will (and had better) return results meeting criteria B. In the case of Unitize( ), the user has every reason to expect that the vector returned will have a norm of 1. Returning something else constitutes a breach of contract.

The problem in this case is not that we can't return a unit vector; that there is no unit vector parallel to the input vector. The problem is that any unit vector is parallel to a vector 0. So, which one should we return?

After dealing with this problem for decades, it finally dawned on me: since any unit vector is satisfactory, let's just pick one. In the exceptional case, I return:

(3)

which is as good a choice as any other.

1 | 2 | 3 | 4

Rate this article: Low High
Current rating
  • .
Embedded.com Career Center
Ready to take that job and shove it?
SEARCH JOBS

Browse all jobs

SPONSOR
RECENT JOB POSTINGS


 :