@@ -210,8 +210,7 @@ final class ElementaryFunctionTests: XCTestCase {
210210 }
211211
212212
213- func testCosSinIdentity< T: Real & FixedWidthFloatingPoint & SIMDScalar > ( _ type: T . Type ) {
214- // For randomly-chosen well-scaled finite values, we expect to have cos² + sin² ≈ 1
213+ func testCos< T: Real & FixedWidthFloatingPoint & SIMDScalar > ( _ type: T . Type ) {
215214 var g = SystemRandomNumberGenerator ( )
216215 let values : [ Quaternion < T > ] = ( 0 ..< 1000 ) . map { _ in
217216 Quaternion (
@@ -224,23 +223,57 @@ final class ElementaryFunctionTests: XCTestCase {
224223 }
225224 for q in values {
226225 let c = Quaternion . cos ( q)
226+
227+ // For randomly-chosen well-scaled finite values, we expect to have
228+ // cos ≈ (e^(q*||v||)+e^(-q*||v||)) / 2
229+ let p = Quaternion ( imaginary: q. imaginary / q. imaginary. length)
230+ let e = ( . exp( p * q) + . exp( - p * q) ) / 2
231+ XCTAssert ( c. isApproximatelyEqual ( to: e) )
232+ }
233+ }
234+
235+ func testSin< T: Real & FixedWidthFloatingPoint & SIMDScalar > ( _ type: T . Type ) {
236+ var g = SystemRandomNumberGenerator ( )
237+ let values : [ Quaternion < T > ] = ( 0 ..< 1000 ) . map { _ in
238+ Quaternion (
239+ real: T . random ( in: - 2 ... 2 , using: & g) ,
240+ imaginary:
241+ T . random ( in: - 2 ... 2 , using: & g) / 3 ,
242+ T . random ( in: - 2 ... 2 , using: & g) / 3 ,
243+ T . random ( in: - 2 ... 2 , using: & g) / 3
244+ )
245+ }
246+ for q in values {
227247 let s = Quaternion . sin ( q)
248+
249+ // For randomly-chosen well-scaled finite values, we expect to have
250+ // cos ≈ (e^(q*||v||)+e^(-q*||v||)) / 2
251+ let p = Quaternion ( imaginary: q. imaginary / q. imaginary. length)
252+ let e = ( . exp( p * q) - . exp( - p * q) ) / ( p * 2 )
253+ XCTAssert ( s. isApproximatelyEqual ( to: e) )
254+
255+ // For randomly-chosen well-scaled finite values, we expect to have
256+ // cos² + sin² ≈ 1
257+ let c = Quaternion . cos ( q)
228258 XCTAssert ( ( c*c + s*s) . isApproximatelyEqual ( to: . one) )
229259 }
230260 }
261+
231262 func testFloat( ) {
232263 testExp ( Float32 . self)
233264 testExpMinusOne ( Float32 . self)
234265 testCosh ( Float32 . self)
235266 testSinh ( Float32 . self)
236- testCosSinIdentity ( Float32 . self)
267+ testCos ( Float32 . self)
268+ testSin ( Float32 . self)
237269 }
238270
239271 func testDouble( ) {
240272 testExp ( Float64 . self)
241273 testExpMinusOne ( Float64 . self)
242274 testCosh ( Float64 . self)
243275 testSinh ( Float64 . self)
244- testCosSinIdentity ( Float64 . self)
276+ testCos ( Float64 . self)
277+ testSin ( Float64 . self)
245278 }
246279}
0 commit comments