No, I don’t mean the “geometric” concept of a point. I mean literally, as in “why bother?” Since vectors is such an overloaded term, let me be clear that I’m only talking about vector analysis (a.k.a. that thing with the cross and dot product).
Topics containing questions about vectors have been (naturally) popping up and I’ve started to respond, then stopped because it’s just too much of a pain to explain in an understandable way. Don’t get me wrong. Vectors aren’t really hard. They are just confusing and difficult to (properly) use for a number of reasons. They are a useful tool to have access to, but they aren’t the only game in town and with additional knowledge of your other choice(s), you just might make your life much easier (and come to grasp vectors in a deeper way).
Now, having said all of that, let me limit what I’m going to babble about. I only really want talk about 2 dimensions. Not the 3 dimensions is any harder, but because I want as many people as possible to follow what I’m saying. Because most people here will have had some exposure to an alternate way to talk about geometric operations without vectors in 2 dimension: complex numbers. Actually I’m kind of hoping that just a little programming and algebra knowledge will be enough to follow. I’ll be throwing in some math-speak so people that haven’t run across the terms before will have a first exposure. A lot of the URLs that I link (MathWorld and Wikipedia) are very formal (aka almost unreadable) but I don’t know of any really down-to-earth descriptions.
Note that I’m not attempting to suggest that things like complex numbers are replacements for vectors. They are a complimentary tool. But most of the time you can do things at least as easy in complex if not significantly easier.
To a certain extent the real purpose of the post has nothing to do with vectors or even mathematics. The attempted “point” is: think outside the box. If you’re having trouble finding a solution, maybe you need to turn it around and look at it from a different point of view. In this case, change the mathematical type that you’re thinking in. As an aside, in some instances the real problem is that you need to change the question.
Tuples
Before saying anything about complex numbers, let’s talk briefly about Tuples, which are an order list of elements (or components). Where each component is accessed by some name or ordinal.
They can be logically used to represent any “chunk” of data. The easiest direct notion of a tuple is an array. Each component is simply referred to by it’s ordinal (position) within the array. Note that there is generally no restriction on what’s stored in the array (so arrays of references are perfectly fine). Some programming languages can only represent data-structures via tuples (notable some functional languages). Objects of prototype based languages have their member fields represented by a mapping of a name to some value, which is another obvious example of something that’s logically a tuple. What perhaps isn’t so obvious that the fields of a language like java are also representable as a tuple. It just simply required choosing some logical ordering of fields. I keep using the term “logical” to point out that this has nothing to do with implementation, and is simply choosing a standardized way to think about the data.
For my purposes here is no reason to go any further with tuples in general and we’ll move directly to n-tuples of real values. (Therefore reals are the scalars) Where ‘n’ is the number of components and each is real value (modeled by some floating point type in implementation). So I’ll write some 2-tuple as <a,b>
, where a & b (as stated) are reals. The common way to write this tuple is (a,b)
, but I’m avoiding that notation for readability reasons. Now let start build up a base type (class) of 2-tuples by defining some functions (operators, methods, whatever ya want to call them).
From now on I’ll write scalar values as small letters and when representing some tuple symbolically as capitals. (I’m using := for definitions)
Define two tuples: X := <a,b> Y := <c,d>
Let’s define addition and subtract to be component by component: X+Y := <a,b> + <c,d> = <a+c, b+d> X-Y := <a,b> - <c,d> = <a-c, b-d>
With subtraction, we can define a negation: -X := -<a,b> = <0,0>-<a,b> = <-a,-b>
And define multiplying by a scalar to distribute (scalar means the type of component…in this case a Real), so for scalar ‘s’: sX := s<a,b> = <sa, sb>
However, since s<a,b>
is a little neater, I’ll leave them written that way rather than expanding.
Now let’s stop and think. We could consider these two values to represent coordinates in the Euclidean plane, where the first is some distance from the origin in ‘x’ and the second is the distance in ‘y’. Actually saying Cartesian would be better, but I’m not that anal today. Then the following is a sample of some geometric interpretations we could make with the operations that we’ve defined:
addition: translation
negation: reflection about the origin (really it’s an inversion…but it’s commonly called a reflection)
scalar multiply: uniform scaling
And since we’re considering the values to be coordinates, we could also formulate various Ln norms and distances, such as L2 (Euclidean, commonly simply called length or distance), L1 (Manhattan) and LInf (Chessboard or Chebyshev).
Choosing the tuple to explicitly represent a coordinate from some predefined origin is exactly what one does when using a vector as a “position vector”. If we subtract one tuple from another, then the result can be consider the “direction” between two (a “direction vector” in, well, vectors). And we could “normalize” this tuple if we felt like it.
Now we could go a step further and note that we could write these tuples in a trig form: m <cos(t), sin(t)>
where, ‘m’ is a positive and ‘t’ is an angle on (-pi, pi]. Although, for the moment, this trig form is of little use, since none of our operations naturally ‘fit’ in this trig form. Notice that the magnitude (L2 norm) of the inside of the tuple is one (sqrt(cos(t)<sup>2</sup>+sin(t)<sup>2</sup>)=1
). Remember that this is just how we’re thinking about the data and doesn’t imply how we’re storing it.
And we could choose to think of the tuple components as represent radically different things: a magnitude and angle for another plane representation (or a cylinder with an implied axis in 3d), a pair of angles for points on a sphere or polar representation of a unit direction, etc. etc.
Basically this is how any mathematical ‘type’ can be looked at. It ‘is’ only the set of properties that it has. Any visualizations, interpretations, etc. are just that. So this 2-tuple can be used for anything we can fit within some sub-set of its properties, but a given usage should be not confused with any intrinsic meaning of the tuple (or type) itself. Also, the functions that I defined above make sense for the kind of tuples we’ll be talking about, but that doesn’t imply that they’re reasonable for all 2-tuples of reals.
Jumping directly to tuples is usually considered to be a “bad” way to learn anything, because it hides the underlying structure of the mathematical type being discussed. I’m of the opinion that, like complex number and vectors, being able to look at something in slightly different ways is always a plus. Sometime one will be more obvious, at other time the other will be. As well as which is the easier way will vary from person to person.
Ok, enough of that…
What’s in a name? And the rules of the game.
Now let’s starting thinking about algebras (I’m being very loose with terminology here. See here if you’re hardcore). In the tuples above, we didn’t assign any names to the components. One way to do so (for an algebra) is to say something like:
“The basis set is {i,j}”.
Now bear with me, 'cause this is kind hard. This is saying the the first component of the tuple is associated with ‘i’ and the second component is associated with ‘j’. Shall I repeat it? Nah. Where the association is an implied multiplication. So for this example, the tuple <x,y>
can be written in an explicit form like this:`
<x,y> = xi + yj`
and the tuple notation is now a shorthand for the above. The names of the basis “i” and “j” act like variables do in plain old algebra with couple slight differences. The first is that they never have a value. The are placeholders that separate the components when written in explicit form in the same way that the commas do in the tuple notation. The second role that they play is that they are used to define the core rules of the algebra, from which everything else springs from. The rules are called either: axioms or postulates.
We won’t bother with any rules for the moment. Going from a basis set and defining axioms and showing how they work is typically called construction. Aside: it’s not uncommon for a given type to have many possible constructions.
Vectors aren’t Complex
Vector analysis is a strange mathematical type for a number of reasons. There’s no point into going into any of my “issues” with vectors, other than one. It doesn’t have a product. As far as the properties of vectors, we’ve already developed all of them (informally…without a basis & axioms) in the section on tuples. Well almost. There are two operators (functions) defined via axioms that we need to add. The cross and dot products. The axioms are a mess, so you can look them up on the web somewhere, if you care. The basis set is {i,j}. Here are the functions (for 2D):`
<a,b> . <c,d> := ac+bd
<a,b> x <c,d> := ad-bc`
Notice that the results of both are scalars and thus cannot be shown in tuple notation. (Actually the cross product result is a bivector, which is the pseudoscalar of 2D…but enough of that, we’ll pretend it’s a scalar) If vectors included a scalar part then they would have an unnamed basis called ‘1’. I know that probably doesn’t make sense yet, but wait for it. The cross and dot product are very useful and there are plenty of resources that describe their properties.
The (Historic) Prisoner
OK. This section can easily be skipped. I want to do two things here. The first is informally show the start of a construction of a family of algebras and the second is to show that considering 'i = sqrt(-1)'
in complex algebra is pretty much historical nonsense. It’s not “invalid” or anything, but it doesn’t provide any helpful insight (in fact I think that it’s harmful). Note that I’m out of the mainstream in this thinking, even considering the fact that it’s a paradox. So if why you can get meaningful results from nonsense doesn’t bother you and seeing a base construction doesn’t interest you…skip to the next bolded section.
Let’s start with a 2-tuple with the basis set {1,e}. The two components are Reals and we have a single axiom: “e2 = k”, where “k” is a Real. The first basis ‘1’ is an unnamed basis and says that we won’t be adding any new rules for it (so it logically acts as multiplying by ‘1’). So for all members of this family tuples in the form <r,0> act like plain old reals.
Let’s form the products for this family of algebras:
Define ‘X’ & ‘Y’: X := <a,b> = a(1)+b[i]e[/i] = a+b[i]e[/i] Y := <c,d> = c(1)+d[i]e[/i] = c+d[i]e[/i]
Expand the product (just like “regular” algebra): XY = (a+b[i]e[/i])(c+d[i]e[/i]) = a(c+d[i]e[/i])+b[i]e[/i](c+d[i]e[/i]) = ac + ad[i]e[/i] + b[i]e[/i]c + b[i]e[/i]d[i]e[/i] = ac + ad[i]e[/i] + bc[i]e[/i] + bd[i]e[/i][i]e[/i] = ac + (ad + bc)[i]e[/i] + bd([i]e[/i]<sup>2</sup>)
From the axiom above we’ve stated that e2 = k and is a real: XY = (ac + bdk) + (ad + bc)[i]e[/i] = <ac+bdk, ad+bc>
Let: k = 0 XY = <ac + bdk, ad + bc> = <ac, ad+bc>
Let: k = 1 XY = <ac + bdk, ad + bc> = <ac+bd, ad+bc>
Let: k = -1 XY = <ac+bdk, ad+bc> = <ac-bd, ad+bc>
When k=0, it form dual numbers, when k=1 forms split-complex numbers and of course when k = -1, then it’s complex numbers. In the complex case, since (what I’m calling e) squares to -1, then e=sqrt(-1) is the mainstream thinking. Consider the other two cases. For dual numbers e2 = 0, then e must be 0 (if it were a number). That means the second component of the tuple can’t exist. x=a(1)+b(0)=a. In the split complex case, well it’s confusing since if ‘e’ where a number it would be either +/-1. As an aside I’ll bring up quaternions. The sqrt(-1) in quaternions has an infinite number of solutions which form a unit sphere. Quaternions can be described as a 4-tuple of reals with the basis set of {1,i,j,k}. Axiom: i2=j2=k2=ijk=-1. The mainstream thinking this means that i, j and k are all sqrt(-1), but that they’re magically independent of one another under addition. Pure silliness IHMO.
Feature creep
OK. I’m running out of steam and haven’t even started to get to the point. Complex numbers. There’s no reason to cover much about them since there are tons of resources on the web, so I’ll just focus on a couple things to make my point and touch on some basics that for some weird reason aren’t talked about.
First is that complex numbers have a product, where vectors have two partial products. Also, complex numbers have a multiplicative inverse. The advantage of having a product and an inverse is that you can manipulation equations algebraically. That way you can reason “algebraically”. Where with vectors one is almost always stuck reasoning geometrically or punting to linear algebra.
Recall the complex product is: <a,b><c,d> = <ac-bd, ad+bc>
. We can now verify that the scalar multiplication that we just defined in the tuple section is valid:
s<x,y> = <s,0><x,y> = <sx-0y, sy-0x> = <sx,sy>
The interesting thing to note is that scale factors can be pulled out. So: (aA)(bB)=ab(AB)
. Combining this with the fact that multiplication distributes: A(B+C) = AB + AC
. These two things together means the complex product is a linear transform.
If we were to think of one as being in the trig form that we had in the tuple section then:
m<cos(t), sin(t)><x,y> = m<x cos(t)-y sin(t), y cos(t) + x sin(t)>
Which is a scaled (by m) counter-clockwise rotation about the origin with an angle of ‘t’. So the product is a scaled rotation if one is considered to represent a scaled rotation and the other to represent a coordinate. If the one that represents the rotation is a unit complex number (m=1), then it’s simply a rotation about the origin. So if we call P a coordinate to rotate, R the rotation and P’ the point after rotation, then we have the super complex equation:
P' = RP
Let’s say that we have unit directions A and B and we want to know how to rotate A into B.
RA = B R = B(1/A) R = BA<sup>*</sup>
(where the superscript star is conjugation…comes up later)
Rotating about the origin is OK, but we really need to be able to rotate about an aribrary point C. Well, let’s translate C to the origin, perform the rotation and then move it back:
P' = R(P-C)+C
I know that most people consider optimization to be bad, but I don’t:
P' = R(P-C)+C = RP-RC+C = RP+C-RC = RP+C(1-R) = RP+T
where T = C(1-R)
. Look at the last line. It is telling you that the rotation R about point C is equivalent to a rotation about the origin R followed by a translation T. And C is recoverable from T & R: C = T/(1-R)
(assuming R isn’t 1).
Now the product of two in trig form:
m<cos(t), sin(t)> n<cos(s), sin(s)> = mn<cos(s)cos(t)-sin(s)sin(t), cos(t)sin(s)+cos(s)sin(t)>
which simplifies by trig identities to:
mn<cos(s+t), sin(s+t)>
Which is the composition of two scaled rotations about the origin. So rotation composition is also the product of two complex numbers.
The conjugate of complex number is defined as:
<a,b><sup>*</sup> = <a,-b>
This definition is by axiom, which along with one for the product form all the properties of complex numbers. Now in trig form:
m<cos(t),sin(t)><sup>*</sup> = m<cos(t),-sin(t)> = m<cos(-t), sin(-t)>
So conjugation negates the angle. Notice that this can be considered a reflection about the line of reals (which we’re thinking of as the ‘x’ axis). Now I could go on and show how to generalize reflections and how rotations, reflections, glide reflections and translation are all related, but my point isn’t a tutorial on complex numbers. So I’ll simply state that generalized reflections and glide reflections can be written as:
P' = RP<sup>*</sup>+D
which is a reflection if RD<sup>*</sup>+D=0
about the axis (line) with the direction of half the angle of R (in trig form) and through the point D/2. Otherwise it’s a glide reflection (about line with direction (RD<sup>*</sup>+D)/2
through point D/2). This equation along with the last rotation cover all the isometries of the plane when the magnitude of R in each is one.
Dude: what’s your point?
I’m getting there. After a brief detour. Complex conjugation is an involution, which is math-speak for a function that is its own inverse. (All reflections are involutions) So if some function ‘F’ is an involution, then F(F(X)) = X
. Which, besides optimiz…err…formula reduction, is frequently used for extract/isolation of parts. Using this technique with addition and the conjugate yield:
(X+X<sup>*</sup>)/2 = (<a,b>+<a,-b>)/2 = <2a,0>/2 = <a,0> (X-X<sup>*</sup>)/2 = (<a,b>-<a,-b>)/2 = <0,2b>/2 = <0,b>
which isolate the real and complex parts respectively. Note that the algebraic form is only useful for equation manipulation and that (of course) you simply grab the parts for computation.
Lets now do the same thing for multiplication:
X^Y := (X<sup>*</sup>Y-XY<sup>*</sup>) = (<a,b><sup>*</sup><c,d>-<a,b><c,d><sup>*</sup>) = <0,ad-bc> X.Y := (X<sup>*</sup>Y+XY<sup>*</sup>) = (<a,b><sup>*</sup><c,d>+<a,b><c,d><sup>*</sup>) = <ac+bd,0>
where I’m using ‘^’ not for raising to a power (since I can do superscripts) but as a symbol for a partial product. We’ll call the first an exterior product and the second an interior product. If you compare the inner product with the vector dot product you’ll notice that they are the same (<ac+bd,0> is scalar ac+bd). The exterior product has the same form as the cross product, except that its result is multiplied by ‘i’ (<0,1>).
Notice that adding the exterior and interior products together yield:
X<sup>*</sup>Y = X.Y + X^Y XY<sup>*</sup> = X.Y - X^Y
So the product of two complex numbers when one is conjugated can be considered to be isolation of relative angle information between the two.
XY<sup>*</sup> = |X||Y|<cos(t),sin(t)>
Which is hopefully obvious if you expand in trig form.
So all the operations that you can perform in 2D vectors can likewise be performed in complex numbers. Complex numbers have the advantage it has more algebraic operators which are relatively easy to manipulate.
My tone has been anti-vectors, but that’s just posing for added impact. Vectors are important. From a practical standpoint so much existing work is in terms of vectors and chances are you’ll be required to learn them. They are also needed from a geometric standpoint as well…I’ll just leave it at that, cause it’s too hard to explain. Just remember that complex numbers and vectors don’t have the same properties, but you can often abuse both to represent things.
Let the flamewar begin.
P.S. I’m sure that somehow this means that Java is dead.
P.P.S. All mistakes are Riven’s fault (assuming that he’s mod that approved this thing)