@@ -276,37 +276,68 @@ extension Quaternion/*: ElementaryFunctions */ {
276276 return Quaternion ( real: . log( q. length) , imaginary: axis * q. halfAngle)
277277 }
278278
279- // MARK: - pow-like functions
280279
281- // pow(q, p) = exp(log(pow(q, p))) = exp(p * log(q))
282280 //
283- // See pow on complex numbers for algorithm details.
284281 @inlinable
285- public static func pow( _ q: Quaternion , _ p: Quaternion ) -> Quaternion {
286- return exp ( p * log( q) )
287282 }
288283
289- // pow(q, n) = exp(log(q) * n)
290284 //
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+
292299 @inlinable
293300 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.
295312 return exp ( log ( q) . multiplied ( by: RealType ( n) ) )
296313 }
297314
298315 @inlinable
299316 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 }
301325 return exp ( log ( q) . divided ( by: 2 ) )
302326 }
303327
304- // root(q, n) = exp(log(q) / n)
305- //
306- // See root on complex numbers for algorithm details.
307328 @inlinable
308329 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.
310341 return exp ( log ( q) . divided ( by: RealType ( n) ) )
311342 }
312343}
0 commit comments