@@ -181,72 +181,26 @@ extension Quaternion/*: ElementaryFunctions */ {
181181
182182 @inlinable
183183 public static func cos( _ q: Quaternion ) -> Quaternion {
184- // Mathematically, this operation can be expanded in terms of
185- // trigonometric `Real` operations as follows (`let θ = ||v||`):
186- //
187- // ```
188- // cos(r + v) = (exp(q * (v/θ)) + exp(-q * (v/θ))) / 2
189- // = cos(r) cosh(θ) - (v/θ) sin(r) sinh(θ)
190- // ```
191- guard q. isFinite else { return q }
192- let ( â, θ) = q. imaginary. unitAxisAndLength
193- guard θ. magnitude < - RealType. log ( . ulpOfOne) else {
194- let rotation = Quaternion ( halfAngle: q. real, unitAxis: â)
195- let firstScale = RealType . exp ( θ. magnitude/ 2 )
196- let secondScale = firstScale/ 2
197- return rotation. multiplied ( by: firstScale) . multiplied ( by: secondScale)
198- }
199- return Quaternion (
200- real: . cosh( θ) * . cos( q. real) ,
201- imaginary: - â * . sinh( θ) * . sin( q. real)
202- )
184+ // cos(q) = cosh(q * (v/θ)))
185+ let ( â, _) = q. imaginary. unitAxisAndLength
186+ let p = Quaternion ( imaginary: â)
187+ return cosh ( q * p)
203188 }
204189
205190 @inlinable
206191 public static func sin( _ q: Quaternion ) -> Quaternion {
207- // Mathematically, this operation can be expanded in terms of
208- // trigonometric `Real` operations as follows (`let θ = ||v||`):
209- //
210- // ```
211- // sin(r + v) = -((exp(q * (v/θ)) - exp(-q * (v/θ))) (v/θ * 2)
212- // = sin(r) cosh(θ) + (v/θ) cos(r) sinh(θ)
213- // ```
214- guard q. isFinite else { return q }
215- let ( â, θ) = q. imaginary. unitAxisAndLength
216- guard θ. magnitude < - RealType. log ( . ulpOfOne) else {
217- let rotation = Quaternion ( halfAngle: q. real, unitAxis: â)
218- let firstScale = RealType . exp ( θ. magnitude/ 2 )
219- let secondScale = RealType ( signOf: θ, magnitudeOf: firstScale/ 2 )
220- return rotation. multiplied ( by: firstScale) . multiplied ( by: secondScale)
221- }
222- return Quaternion (
223- real: . cosh( θ) * . sin( q. real) ,
224- imaginary: â * . sinh( θ) * . cos( q. real)
225- )
192+ // sin(q) = -(v/θ) * sinh(q * (v/θ)))
193+ let ( â, _) = q. imaginary. unitAxisAndLength
194+ let p = Quaternion ( imaginary: â)
195+ return - p * sinh( q * p)
226196 }
227197
228198 @inlinable
229199 public static func tan( _ q: Quaternion ) -> Quaternion {
230- // Mathematically, this operation can be expanded in terms of
231- // trigonometric `Real` operations as follows (`let θ = ||v||`):
232- //
233- // ```
234- // tan(q) = sin(q) / cos(q)
235- // ```
236- guard q. isFinite else { return q }
237- // Note that when |θ| is larger than -log(.ulpOfOne),
238- // sin(r + v) == ±cos(r + v), so tan(r + v) is just ±1.
239- guard q. imaginary. length. magnitude < - RealType. log ( . ulpOfOne) else {
240- let r = RealType ( signOf: q. components. w, magnitudeOf: 1 )
241- return Quaternion (
242- real: r,
243- imaginary:
244- RealType ( signOf: q. components. x, magnitudeOf: 0 ) ,
245- RealType ( signOf: q. components. y, magnitudeOf: 0 ) ,
246- RealType ( signOf: q. components. z, magnitudeOf: 0 )
247- ) . multiplied ( by: r)
248- }
249- return sin ( q) / cos( q)
200+ // tan(q) = -(v/θ) * tanh(q * (v/θ)))
201+ let ( â, _) = q. imaginary. unitAxisAndLength
202+ let p = Quaternion ( imaginary: â)
203+ return - p * tanh( q * p)
250204 }
251205
252206 // MARK: - log-like functions
0 commit comments