27

I know that quaternions need to be normalized if I want to rotate a vector.

But are there any reasons to not automatically normalize a quaternion? And if there are, what quaternion operations do result in non-normalized quaternions?

  • Multiplying two quaternions?
  • Dot product?

Sorry, if this question is a little bit fuzzy. I'm still trying wrap my head around quaternions.

Sebastian Krysmanski
  • 8,114
  • 10
  • 49
  • 91
  • Technically, any quaternion represents a valid rotation, if you use it right, i.e., `q x v x q^-1` instead of `q x v x q*`. There is an implicit normalization that results in the rotation matrix as well. – Mad Physicist Apr 29 '20 at 14:32

6 Answers6

44

Late response; this answer is for people who come across this question in the future rather than for the questioner.

I disagree with the other two answers regarding only normalizing a quaternion occasionally. The standard formulae for using a quaternion to rotate/transform a vector or to generate a rotation/transformation matrix implicitly assume the quaternion is normalized. The errors that result from using an unnormalized quaternion are proportional to the square of the quaternion's magnitude. Quadratic error growth is something best avoided.

If you normalize frequently you don't need square root. A first order approximation works quite nicely. Here's what I use for quaternions as IEEE doubles, somewhat stylized:

double qmagsq = quat.square_magnitude();
if (std::abs(1.0 - qmagsq) < 2.107342e-08) {
    quat.scale (2.0 / (1.0 + qmagsq));
}
else {
    quat.scale (1.0 / std::sqrt(qmagsq));
}

Note that I'm using the first order Padé approximant 2.0/(1.0+qmagsq) rather than the first order Taylor expansion 0.5*(3.0-qmagsq) to estimate 1.0/std::sqrt(qmagsq). This approximation, if valid, replaces the square root call by a simple division. The key is to find when that approximation is valid, which is where that magic number 2.107342e-08 comes into play.

Why a Padé approximant? Two reasons. One is that for values of qmagsq close to one, 1+qmagsq loses less precision than does 3-qmagsq. The other is that the Padé approximant cuts the error by a factor of three compared to the Taylor expansion. For values of qmagsq between 0 and 2, the error in this approximation is less than (1-qmagsq)^2 / 8. The magic number 2.107342e-08 represents where this error is more that half an ULP for IEEE doubles. If you are taking reasonable small steps, the square of the magnitude of the quaternion will always be within that limit. You'll never be calling sqrt.

The one exception to this "normalize always" paradigm might be if you are using a Lie group integration technique to propagate quaternions. If you don't know what that means, you are probably using the equivalent of q(t+Δt) = q(t) + dq(t)/dt*Δt to propagate a quaternion. You're still using that Euler step somewhere even if you are using a higher order integration technique that isn't a Lie group integrator.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • Are you aware of any tests & statistics for error accumulation w/o normalization, with pure `sqrt`-based, and with approximate normalization? Note 1: "The standard formulae... implicitly assume"---there are no de jure standard formulae, are there? Any formula may be used, as long as it is correct according to quaternion calculus, and your problem's specific requirements. Note 2: for transformation matrices calculated as in my answer, the absolute error is proportional to magnitude^2, but the relative error (which is more important) is not. Note 3: normalization introduces additional errors. – vpozdyayev Oct 18 '12 at 06:19
  • 5
    Normalization is a kludge to drag the quaternion back to the unit 3-sphere. The reason quaternions drift off the manifold is because that Euler step is in a sense invalid mathematically: The unit quaternions are a group, not an algebra. Not using unit quaternions is also invalid; now you don't have a chart on so(3). Do it right (e.g., Lie group integration techniques) and the quaternion will pretty much stay on the manifold. You might still need to normalize occasionally. – David Hammen Oct 18 '12 at 12:59
  • 1
    As far as my square root approximation is concerned: By design it's accurate to within half an ULP over its design range. It occasionally differs from `1/std::sqrt(x)` in the least significant bit, but that's because `std::sqrt(x)` is also accurate to within half an ULP. Which answer is right when they do differ? Neither one. The right answer is halfway in between. – David Hammen Oct 18 '12 at 13:03
  • 1
    These are valid considerations, for this kind of problem. However, unlike the answers you criticize, they have nothing to do with the original question of existence or nonexistence of "reasons to not automatically normalize a quaternion" (as in, using unnormalized quaternions, not just trying to maintain their magnitudes w/o renormalization). Your answer provides a counterexample, but it does not disprove existence of other problems with different requirements regarding normalization. – vpozdyayev Oct 19 '12 at 10:38
  • instead of `2.0 / (1.0 + qmagsq)` you should better use `2.0 - 0.5*qmagsq` (first Taylor approximation of 1/sqrt(x) at x=1). The boundary where you get 0.5ULP error might be slightly different (and it may be acceptable to have 1 or 2 ULP error for some people) – chtz Oct 30 '17 at 10:49
  • 2
    @chtz - The first order Taylor approximation of `1/sqrt(x)` about x=1 is `(3-x)/2`, and it's about 3 times worse in terms of error than is `2/(1+x)` for x near 1. Sometimes Padé approximants are quite magical. This is one of the cases where the magic works quite nicely. – David Hammen Oct 30 '17 at 15:31
  • 2
    Do you know the magic number for IEEE single precision (`float`) floating-point numbers? – plasmacel Apr 05 '19 at 19:51
  • "The errors that result from using an unnormalized quaternion are proportional to the square of the quaternion's magnitude." Are you sure? Maybe that's technically true in terms of absolute error, but absolute error isn't really of much relevance here. When viewed as objects in the homogeneous space, any quaternion is just as good as any other positive multiple of it, in theory and in practice using IEEE754; really the only reason I can think of for normalizing a quaternion is to prevent overflow/underflow. – Don Hatch May 27 '22 at 17:48
  • @DonHatch The typical use of quaternions to represent rotations assumes a unit quaternion. This means the inverse **is** the conjugate, which in turn enables huge speedups in the math compared to explicitly calculating the inverse. Multiple open source implementations explicitly make this assumption and warn the user that the quaternions used to represent 3D rotation should indeed be unit quaternions. – David Hammen May 27 '22 at 19:21
  • @DavidHammen that makes sense, thanks for explaining. – Don Hatch May 27 '22 at 19:31
11

Any operation that produces a quaternion will need to be normalized because floating-point precession errors will cause it to not be unit length.

I would advise against standard routines performing normalization automatically for performance reasons. Any competent programmer should be aware of the precision issues and be able to normalize the quantities when necessary - and it is not always necessary to have a unit length quaternion.

The same is true for vector operations.

  • 3
    This is just premature optimization: make the developer do extra error-prone work even when it doesn't matter. – Glenn Maynard Jun 01 '16 at 02:11
  • 1
    If you wouldn't mind, what is a typical strategy for tuning this sort of thing? Would you just test all your implementations for speed and accuracy, in combination with one another, or would you have a strategy in mind? For instance, I would expect more denormalization from mixed addition and multiplication, and prioritize accuracy there. But I wouldn't know when I could get away with it or should try, and I'll end up making a slider from glitchy to laggy without any idea how to avoid both. – John P Dec 08 '18 at 11:39
  • @JohnP. Work out the math. If you can use the fact that any quaternion is some norm times a unit quaternion, do so. For example, if you're multiplying, inverting, conjugating, etc, you can save the normalization to the very end, or just ignore it. The only time you *really* need a normalized quaternion is when you use it as a rotor. – Mad Physicist Jun 02 '21 at 21:46
7

Funnily enough, building rotation matrices is one operation where normalizing quaternions is NOT needed, saving you one sqrt:

M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y),    2*(w*y+x*z);
     2*(w*z+x*y),     w*w-x*x+y*y-z*z, 2*(-w*x+y*z);
     2*(-w*y+x*z),    2*(w*x+y*z),     w*w-x*x-y*y+z*z] / (w*w+x*x+y*y+z*z)

(in a MATLAB-ish notation) for the quaternion w+x*i+y*j+z*k.

Moreover, if you are working with homogeneous coordinates and 4x4 transformation matrices, you can also save some division operations: just make a 3x3 rotation part as if the quaternion was normalized, and then put its squared length into the (4,4)-element:

M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y),    2*(w*y+x*z),     0;
     2*(w*z+x*y),     w*w-x*x+y*y-z*z, 2*(-w*x+y*z),    0;
     2*(-w*y+x*z),    2*(w*x+y*z),     w*w-x*x-y*y+z*z, 0;
     0,               0,               0,               w*w+x*x+y*y+z*z].

Multiply by a translation matrix, etc., as usual for a complete transformation. This way you can do, e.g.,

[xh yh zh wh]' = ... * OtherM * M * [xold yold zold 1]';
[xnew ynew znew] = [xh yh zh] / wh.

Normalizing quaternions at least occasionally is still recommended, of course (it may also be required for other operations).

vpozdyayev
  • 1,014
  • 5
  • 14
  • That matrix M is not a proper transformation matrix if the quaternion isn't normalized. The formula used implicitly assumes a normalized quaternion. – David Hammen Oct 17 '12 at 12:09
  • 1
    @DavidHammen: It is a proper transformation matrix, if you are working with homogeneous coordinates. In that case, matrices `M` and `a*M` are essentially the same for any non-zero `a`---and this matrix is exactly the matrix obtained from a normalized quaternion, then scaled by `w*w+x*x+y*y+z*z`. – vpozdyayev Oct 18 '12 at 05:51
  • No, it isn't. Calculate the determinant. It's not one. Calculate M*transpose(M). It's not an identity matrix. This is exactly what I was addressing about when I wrote "standard formulae". This is one of those standard formulae, and it implicitly assumes a normalized quaternion. There's an easy, square root-free fix for this particular application of quaternions: Simply divide every element by `w*w+x*x+y*y+z*z`, and voila, you have a proper transformation matrix. – David Hammen Oct 18 '12 at 10:52
  • 6
    @DavidHammen: (1) You seem to assume that transformation matrices must be orthogonal. Even if it's true in your line of work, this is not a requirement in general. You understand what "homogeneous coordinates" means, right? (2) Sqrt-free calculations involving division by `w*w+x*x+y*y+z*z` is exactly what I meant by the very first statement (in the answer). The 4x4 matrix itself is a division-free fix. – vpozdyayev Oct 18 '12 at 12:52
  • @DavidHammen: I have added some equations to the answer. Please comment if you feel that it could use yet more details. – vpozdyayev Oct 26 '12 at 12:41
2

If a unit quaternion is obtained by numerically integrating its first time derivative, the integrator can automatically normalize it using a simple error feedback.

Let q represent a 4 by 1 column matrix of quaternions and dq its time derivative. Then sending dq+0.5(1-q.q)q/tau to the integrator in place of dq and using a suitable time constant tau will continuously normalize q. q.q represents the inner product.

I simulated a conservative, articulating Bricard mechanism floating in gravity-free space for 3.6 million seconds, which is nearly 42 days. Quaternions represented the floating base body's orientation. The total energy remained constant to within one part per million using a time constant tau of 0.5 seconds. An absolute error tolerance of 10^-12 and a relative error tolerance of zero was used in the numerical integrator DE.

http://www.amazon.com/Computer-Solution-Ordinary-Differential-Equations/dp/0716704617/

Quaternions are often obtained by numerical integration. If they are not normalized inside the integrator, then magnitude and phase errors will accumulate. A normalized quaternion moves along a unit sphere, and its first time derivative is tangent to that sphere. If the quaternion drifts away from the unit sphere, it will begin to accumulate phase errors that normalizing outside the integrator cannot correct. So the quaternion must be continuously normalized within the numerical integrator to minimize phase errors.

Roger Wehage
  • 109
  • 4
0

your question is ambigious but if u need to normalize a quaternion is simple

q_normalized = q /square(norm(q))

with, q = q1 +q2i +q3 j +q4 k norm (q) = (q1)^2 + (q2)^2 + (q3)^2) + (q4)^4

if else explain to me your question

Amal Kostali Targhi
  • 907
  • 3
  • 11
  • 22
-1

Use of NONunit quaternions can be efficient.

Only few operations require unit length, for example interpolation.

Some tips:

  1. Creating and conversions to nonunit quaternions can be more efficient.
  2. Conversion to matrix from nonunit quaternion is still fast. Just compensate scale of quaternion squared.
  3. conversion matrix to nonunit quat is faster.

So it is not required to use only unit quaternions, it is just common practice. For every use case you can make decision use or not normalization. Personally i prefer to use nonunit quaternions.

WARNING: often, working with unit quaternions, we forget about numerical errors. For example, converting from/to matrix quaternion and thinking that it still unit make big numerical unstability, matrix is scaled , quaternions extracted is invalid. You can easy make such experiment.

minorlogic
  • 1,872
  • 1
  • 17
  • 24