Home
Ben FrantzDale - Affine & Vector Spaces [entries|archive|friends|userinfo]
Ben FrantzDale

[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Affine & Vector Spaces [Jan. 9th, 2007|07:28 pm]
Previous Entry Add to Memories Tell a Friend Next Entry
[Tags|, , ]

I recently got an answer to something that's been bugging me for quite a while.

When you first learned about vectors, the teacher probably drew an arrow and said this arrow, x, represents a displacement!, or something similar. Then the teacher probably said something like
Suppose we are at some point x [draws arrow from an origin to some point] and then we move to some other point, y [draws another arrow from the origin]. We can express the distance from x to y by d=xy [draws another arrow from the tip of x to the tip of y and labels it d].

The description probably went on say that you can add them and multiply them by scalars. It's all quite spiffy. The teacher might have even said the space we live in (being isomorphic to R3) is a vector space.

But what does it mean to multiply a point in space by 2? and why did the points in space get drawn with their tails at some arbitrary origin when the displacement was drawn floating out in space?

Here's what's going on.


The world we live in is really better described as an affine space. An affine space is essentially a vector space that has forgotten its origin. That is why two times (the location of Timbuktu) makes no sense: there is no origin to make it twice as far away from.
  • Affine points, as they are called, cannot be added or multiplied by scalars.
  • You can take a difference between affine points. This produces a displacement vector. (A displacement is a vector because a zero displacement is very meaningful, as is doubling a displacement.)
  • You can add a displacement to a point (e.g., go right 10 feet) to get a new point.


In general, natural operations on affine points include translation and rotation about a point (among other things). These are called affine transformations. While you can't take a linear combination of affine points (because you can't do scalar multiplication or addition), you can take affine combinations of points, which is essentially interpolation among several points.

Without cheating, you can take the average of several affine points using an algorithm like this:
int count = 0;
point mean; // Can be initialized to any point in space
for each point p
  n = n + 1;
  mean = mean + (p - mean) / n;


Vectors can be rotated, scaled, and displaced, but they have an origin, so while rotating the vector 10 feet right by 180° makes sense (and is equal to 10 feet left), it makes no sense to rotate that vector by 180° about the displacement one mile up. (Strictly speaking, that is a legal operation, as a vector space can be thought of as an affine space with an origin, addition, and scalar multiplication.)

So there you have it. The “points” your teacher drew were really the displacements from the origin to points. The picture wasn't of any one space – it was a combination of the affine space of points and the vector space of displacements.

That displacement vector, d, is equal to any other vector on that board with the same direction and magnitude. (To draw vectors in the vector space of displacements you'd draw them so their tails are all in one place – the origin.)

One more thing...


There is a less-discussed object, a bound vector, which is simply a vector with a location in space. For example, the water at the middle of the river is moving at 5 meters per second. As far as I can tell, if you fill space with these, you get a vector field. (This sheds some light on how a vector field is different from a vector space.)

Thanks to Arthur Rubin at the Wikipedia math reference desk for introducing me to affine spaces.
linkReply

Comments:
[User Picture]From: [info]goawaystupidai
2007-01-10 04:24 am (UTC)

(Link)

Interesting! But I'm surprised there is no mention of how a strong type system can be used to enforce these semantics while programming. ;-)

OK OK. I figure it was only to keep the post on a single topic. I've always found it entertaining to find ways to represent the two with types with relations that support the different semantics but with implementations that maximize code reuse between the two. The one sticking part, for me, is what to call the entity that defines the common aspects of the implementations. I've used "basis" in the "the underlying support or foundation for an idea, argument, or process" sense before. However, "basis" means something more specific in linear algebra so I don't really like it. Any ideas?

For instance:
In O'Caml, I played with an implementation like this:

type basisType = [`Point | `Vector];;

type 'a basis =
{ x : float; y : float; z : float; }
constraint 'a = [< basisType ];;

type point = [`Point] basis;;
type vector = [`Vector] basis;;


Notice vector and point were defined as parameterizations of a type. In this case I used "basis" as the types name.

In C++ I did something similar and used basis in the types name also.

Maybe "value array"?
[User Picture]From: [info]benfrantzdale
2007-01-10 06:10 am (UTC)

(Link)

I thought you'd be interested in this one. You know me, strong typing is definitely underlying this post.

As for what word to use, I think base is the right word. That's what the g++ STL implementation uses. In bits/stl_vector.h you'll see this:
class vector : protected _Vector_base<_Tp, _Alloc>


I'm not literate in O'Caml, but I know what you mean. In this case I think we can just be mathematically pedantic to figure out how to do it: if an affine space is a vector space without an origin, then a vector is an affine point with some additional properties. Then we could just do
struct affine_point3 {
  double data[3];
  // ...
};

struct vector3 : public affine_point {};

double operator*(const vector3& a,
                 const vector3& b) {
  return std::inner_product(a.data, a.data + 3,
                            b.data,
                            0.0);
}

// etc.

Of course, to be fully generic we don't want to limit ourselves to three-dimensional space; we should be prepared to deal with abstract points such as functions or sequences.
[User Picture]From: [info]thegreatgonz
2007-01-10 07:03 am (UTC)

(Link)

Cool. The word 'affine' is very familiar to me from a graphics point of view, because the affine transformations are the ones you generally want to apply to objects (the linear transformations being inadequate because they do not allow translation). I don't immediately see why the affine transformations would be a superset of the linear transformations, though; from the above it seems like they ought to be a subset. I haven't thought about it much, though.
[User Picture]From: [info]benfrantzdale
2007-01-10 07:19 am (UTC)

(Link)

Affine transformations are a superset of linear transformations because all linear transformations are affine transformations. In particular, they are the affine transformations with a center of rotation of the origin.

The rest of the affine transformations are nonlinear (in n dimensions). As I understand it, homogeneous coordinates are used in graphics because in n+1 dimensions, affine transformations are linear (allowing the magic of the OpenGL matrix stacks to work).
[User Picture]From: [info]amoken
2007-01-17 05:09 am (UTC)

(Link)

I work with AffineTransforms a fair bit. Mostly with the graph (that's nodes-and-edges type graphs, not charts) package we use. They're involved in many bits, mostly transforming between graph-space and screen-space and another space that's a little annoyingly complicated. :) I have to make some tweaks to the EdgeRenderer soon, so I'll be messing with them again....