Remix.run Logo
srean 5 hours ago

META: Pulling this out of its original context because I think more readers would find the code amusing. I am breaking the rules, but hopefully for a good/pardonable reason.

> Most of the time we think of complex numbers as vectors in R2 or as rotation+scaling operators, but rarely do we actually we want them in both roles at the same time.

I can give one counterexample.

I was asked to comment on a piece of code that did 2D geometry in Python. There was one piece that was a tangle of trigonometry to find the angular bisector of an angle subtended at the origin by two points.

Using the fact that points can be represented by complex numbers and that rotation is just multiplication one can make that function into a one liner.

      √(z1 * z2)
The geometric mean of the two points as represented by complex numbers gives you the bisector. Python has native support for complex numbers so all the computation is handled by the runtime.
Chinjut 5 hours ago | parent [-]

This is like how one often wants to distinguish the points of an affine space from the vectors representing displacements in that space (there is no distinguished origin for the physical world, but there is a distinguished concept of zero displacement). One can add a vector to a point to get a point, or a vector to a vector to get a vector, but cannot add a point to a point to get another point. Yet, it is meaningful to treat a linear combination of points in an affine space as yielding another point in the same space when the weights of the linear combination sum to 1.

The exact same thing is happening here, only multiplicatively, where z1^(1/2) * z2^(1/2) is a combination with two weights of 1/2 (thus, summing to 1). It is geometrically meaningful to treat 2d vectors (displacements in a plane) as complex numbers, raise them to exponents summing to 1, and then multiply these together to get another vector in the same plane. But it is not generally geometrically meaningful to just multiply one vector by another vector to get a third vector in the same space (because this would require distinguishing some particular direction and magnitude as "1").

srean 5 hours ago | parent [-]

I agree with you on three dimensional vector products. It's too special, too cute and doesn't generalize to all dimensions, and as you said, you have to keep track of the two types of vectors.

On complex multiplications though, I disagree. It's a great way to do Euclidean manipulations on the 2d plane. Rotations, translations and reflections (via conjugates) are simple. You rarely need calls to trigonometric functions.

If you have runtime support, it's sorta criminal not to use complex multiplication when applicable.

BTW there is another, equivalent, way of deriving the solution which to me seems more intuitive (and not limited to sum of powers to 1):

The angular travel from z1 to z2 is

   z2 / z1. 
I want to travel half of that, so

   √(z2/z1). 
This half travel I apply to z1 like so

    √(z2/z1) * z1
done.

If the need was to continue to travel angularly (rotate) beyond z2, say double the subtended angle, that's easy too. No need for the constraint the sum of powers be 1.

srean an hour ago | parent | next [-]

@chinjut yes you are exactly right about sum to 1 bit.

For a moment I had got distracted by the exponential between Lie group and algebra.

ajkjk 4 hours ago | parent | prev [-]

What magnitude are you expecting your angle bisector to have afterwards?

srean 4 hours ago | parent [-]

There was only the need for the point on the bisector (on the unit circle). There was no need for the magnitude of the angle.

The only thing that needed care was which sign of the sqrt bisects the internal angle as opposed to the external angle.

In general I prefer not to deal with angles when dealing with 2D rotation. Get inputs in angles if need be and from then onwards use the (cos,sin) tuple or, equivalently, use complex numbers. One can get rid of calls to trascendentals as long as you are happy to call sqrt.

In other words angle is a tuple.

ajkjk 4 hours ago | parent [-]

if they're unit vectors then yes that makes a lot of sense.

The same calculation works in R^n, incidentally, using the geometric product. This is pretty much the ideal usecase for it, for constructing operators between vectors.

srean 4 hours ago | parent [-]

Maybe that's my missing link for

https://news.ycombinator.com/item?id=48619191

You probably know this, but this is one way to generalize beyond 2D

https://en.wikipedia.org/wiki/Angle_bisector_theorem