Skip to content

Commit cdc35be

Browse files
committed
Add an early skip when calculating the length in exp
1 parent 4dbe2e8 commit cdc35be

File tree

1 file changed

+4
-9
lines changed

1 file changed

+4
-9
lines changed

Sources/QuaternionModule/ElementaryFunctions.swift

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,10 @@ extension Quaternion/*: ElementaryFunctions */ {
3131
/// `exp(r) cos(θ)` would not be).
3232
public static func exp(_ q: Quaternion<RealType>) -> Quaternion<RealType> {
3333
guard q.isFinite else { return q }
34-
// Firstly evaluate θ and v/θ where θ = ||v|| (as discussed above)
35-
// There are 2 special cases for ||v|| that we need to take care of:
36-
// The value of ||v|| may be invalid due to an overflow in `.lengthSquared`.
37-
// As the internal `SIMD3.length` helper functions deals with overflow and
38-
// underflow of `.lengthSquared`, we can safely ignore this case here.
39-
// However, we still have to check for ||v|| = 0 before evaluating v/θ
40-
// as it would incorrectly yield a division by zero.
41-
let phase = q.imaginary.length
42-
let unitAxis = !phase.isZero ? (q.imaginary / phase) : .zero
34+
// For real quaternions we can skip phase and axis calculations
35+
// TODO: Replace q.imaginary == .zero with `q.isReal`
36+
let phase = q.imaginary == .zero ? .zero : q.imaginary.length
37+
let unitAxis = q.imaginary == .zero ? .zero : (q.imaginary / phase)
4338
// If real < log(greatestFiniteMagnitude), then exp(q.real) does not overflow.
4439
// To protect ourselves against sketchy log or exp implementations in
4540
// an unknown host library, or slight rounding disagreements between

0 commit comments

Comments
 (0)