@@ -276,37 +276,68 @@ extension Quaternion/*: ElementaryFunctions */ {
276
276
return Quaternion ( real: . log( q. length) , imaginary: axis * q. halfAngle)
277
277
}
278
278
279
- // MARK: - pow-like functions
280
279
281
- // pow(q, p) = exp(log(pow(q, p))) = exp(p * log(q))
282
280
//
283
- // See pow on complex numbers for algorithm details.
284
281
@inlinable
285
- public static func pow( _ q: Quaternion , _ p: Quaternion ) -> Quaternion {
286
- return exp ( p * log( q) )
287
282
}
288
283
289
- // pow(q, n) = exp(log(q) * n)
290
284
//
291
- // See pow on complex numbers for algorithm details.
285
+ // MARK: - pow-like functions
286
+
287
+ @inlinable
288
+ public static func pow( _ q: Quaternion , _ p: Quaternion ) -> Quaternion {
289
+ // Mathematically, this operation can be expanded in terms of the
290
+ // quaternionic `exp` and `log` operations as follows:
291
+ //
292
+ // ```
293
+ // pow(q, p) = exp(log(pow(q, p)))
294
+ // = exp(p * log(q))
295
+ // ```
296
+ exp ( p * log( q) )
297
+ }
298
+
292
299
@inlinable
293
300
public static func pow( _ q: Quaternion , _ n: Int ) -> Quaternion {
294
- if q. isZero { return . zero }
301
+ // Mathematically, this operation can be expanded in terms of the
302
+ // quaternionic `exp` and `log` operations as follows:
303
+ //
304
+ // ```
305
+ // pow(q, n) = exp(log(pow(q, n)))
306
+ // = exp(log(q) * n)
307
+ // ```
308
+ guard !q. isZero else { return . zero }
309
+ // TODO: this implementation is not quite correct, because n may be
310
+ // rounded in conversion to RealType. This only effects very extreme
311
+ // cases, so we'll leave it alone for now.
295
312
return exp ( log ( q) . multiplied ( by: RealType ( n) ) )
296
313
}
297
314
298
315
@inlinable
299
316
public static func sqrt( _ q: Quaternion ) -> Quaternion < RealType > {
300
- if q. isZero { return . zero }
317
+ // Mathematically, this operation can be expanded in terms of the
318
+ // quaternionic `exp` and `log` operations as follows:
319
+ //
320
+ // ```
321
+ // sqrt(q) = q^(1/2) = exp(log(q^(1/2)))
322
+ // = exp(log(q) * (1/2))
323
+ // ```
324
+ guard !q. isZero else { return . zero }
301
325
return exp ( log ( q) . divided ( by: 2 ) )
302
326
}
303
327
304
- // root(q, n) = exp(log(q) / n)
305
- //
306
- // See root on complex numbers for algorithm details.
307
328
@inlinable
308
329
public static func root( _ q: Quaternion , _ n: Int ) -> Quaternion {
309
- if q. isZero { return . zero }
330
+ // Mathematically, this operation can be expanded in terms of the
331
+ // quaternionic `exp` and `log` operations as follows:
332
+ //
333
+ // ```
334
+ // root(q, n) = exp(log(root(q, n)))
335
+ // = exp(log(q) / n)
336
+ // ```
337
+ guard !q. isZero else { return . zero }
338
+ // TODO: this implementation is not quite correct, because n may be
339
+ // rounded in conversion to RealType. This only effects very extreme
340
+ // cases, so we'll leave it alone for now.
310
341
return exp ( log ( q) . divided ( by: RealType ( n) ) )
311
342
}
312
343
}
0 commit comments