annotate DEPENDENCIES/generic/include/boost/math/quaternion.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // boost quaternion.hpp header file
Chris@16 2
Chris@16 3 // (C) Copyright Hubert Holin 2001.
Chris@16 4 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 5 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 // See http://www.boost.org for updates, documentation, and revision history.
Chris@16 9
Chris@16 10 #ifndef BOOST_QUATERNION_HPP
Chris@16 11 #define BOOST_QUATERNION_HPP
Chris@16 12
Chris@16 13
Chris@16 14 #include <complex>
Chris@16 15 #include <iosfwd> // for the "<<" and ">>" operators
Chris@16 16 #include <sstream> // for the "<<" operator
Chris@16 17
Chris@16 18 #include <boost/config.hpp> // for BOOST_NO_STD_LOCALE
Chris@16 19 #include <boost/detail/workaround.hpp>
Chris@16 20 #ifndef BOOST_NO_STD_LOCALE
Chris@16 21 #include <locale> // for the "<<" operator
Chris@16 22 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 23
Chris@16 24 #include <valarray>
Chris@16 25
Chris@16 26
Chris@16 27
Chris@16 28 #include <boost/math/special_functions/sinc.hpp> // for the Sinus cardinal
Chris@16 29 #include <boost/math/special_functions/sinhc.hpp> // for the Hyperbolic Sinus cardinal
Chris@16 30
Chris@16 31
Chris@16 32 namespace boost
Chris@16 33 {
Chris@16 34 namespace math
Chris@16 35 {
Chris@16 36
Chris@16 37 #define BOOST_QUATERNION_ACCESSOR_GENERATOR(type) \
Chris@16 38 type real() const \
Chris@16 39 { \
Chris@16 40 return(a); \
Chris@16 41 } \
Chris@16 42 \
Chris@16 43 quaternion<type> unreal() const \
Chris@16 44 { \
Chris@16 45 return(quaternion<type>(static_cast<type>(0),b,c,d)); \
Chris@16 46 } \
Chris@16 47 \
Chris@16 48 type R_component_1() const \
Chris@16 49 { \
Chris@16 50 return(a); \
Chris@16 51 } \
Chris@16 52 \
Chris@16 53 type R_component_2() const \
Chris@16 54 { \
Chris@16 55 return(b); \
Chris@16 56 } \
Chris@16 57 \
Chris@16 58 type R_component_3() const \
Chris@16 59 { \
Chris@16 60 return(c); \
Chris@16 61 } \
Chris@16 62 \
Chris@16 63 type R_component_4() const \
Chris@16 64 { \
Chris@16 65 return(d); \
Chris@16 66 } \
Chris@16 67 \
Chris@16 68 ::std::complex<type> C_component_1() const \
Chris@16 69 { \
Chris@16 70 return(::std::complex<type>(a,b)); \
Chris@16 71 } \
Chris@16 72 \
Chris@16 73 ::std::complex<type> C_component_2() const \
Chris@16 74 { \
Chris@16 75 return(::std::complex<type>(c,d)); \
Chris@16 76 }
Chris@16 77
Chris@16 78
Chris@16 79 #define BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(type) \
Chris@16 80 template<typename X> \
Chris@16 81 quaternion<type> & operator = (quaternion<X> const & a_affecter) \
Chris@16 82 { \
Chris@16 83 a = static_cast<type>(a_affecter.R_component_1()); \
Chris@16 84 b = static_cast<type>(a_affecter.R_component_2()); \
Chris@16 85 c = static_cast<type>(a_affecter.R_component_3()); \
Chris@16 86 d = static_cast<type>(a_affecter.R_component_4()); \
Chris@16 87 \
Chris@16 88 return(*this); \
Chris@16 89 } \
Chris@16 90 \
Chris@16 91 quaternion<type> & operator = (quaternion<type> const & a_affecter) \
Chris@16 92 { \
Chris@16 93 a = a_affecter.a; \
Chris@16 94 b = a_affecter.b; \
Chris@16 95 c = a_affecter.c; \
Chris@16 96 d = a_affecter.d; \
Chris@16 97 \
Chris@16 98 return(*this); \
Chris@16 99 } \
Chris@16 100 \
Chris@16 101 quaternion<type> & operator = (type const & a_affecter) \
Chris@16 102 { \
Chris@16 103 a = a_affecter; \
Chris@16 104 \
Chris@16 105 b = c = d = static_cast<type>(0); \
Chris@16 106 \
Chris@16 107 return(*this); \
Chris@16 108 } \
Chris@16 109 \
Chris@16 110 quaternion<type> & operator = (::std::complex<type> const & a_affecter) \
Chris@16 111 { \
Chris@16 112 a = a_affecter.real(); \
Chris@16 113 b = a_affecter.imag(); \
Chris@16 114 \
Chris@16 115 c = d = static_cast<type>(0); \
Chris@16 116 \
Chris@16 117 return(*this); \
Chris@16 118 }
Chris@16 119
Chris@16 120
Chris@16 121 #define BOOST_QUATERNION_MEMBER_DATA_GENERATOR(type) \
Chris@16 122 type a; \
Chris@16 123 type b; \
Chris@16 124 type c; \
Chris@16 125 type d;
Chris@16 126
Chris@16 127
Chris@16 128 template<typename T>
Chris@16 129 class quaternion
Chris@16 130 {
Chris@16 131 public:
Chris@16 132
Chris@16 133 typedef T value_type;
Chris@16 134
Chris@16 135
Chris@16 136 // constructor for H seen as R^4
Chris@16 137 // (also default constructor)
Chris@16 138
Chris@16 139 explicit quaternion( T const & requested_a = T(),
Chris@16 140 T const & requested_b = T(),
Chris@16 141 T const & requested_c = T(),
Chris@16 142 T const & requested_d = T())
Chris@16 143 : a(requested_a),
Chris@16 144 b(requested_b),
Chris@16 145 c(requested_c),
Chris@16 146 d(requested_d)
Chris@16 147 {
Chris@16 148 // nothing to do!
Chris@16 149 }
Chris@16 150
Chris@16 151
Chris@16 152 // constructor for H seen as C^2
Chris@16 153
Chris@16 154 explicit quaternion( ::std::complex<T> const & z0,
Chris@16 155 ::std::complex<T> const & z1 = ::std::complex<T>())
Chris@16 156 : a(z0.real()),
Chris@16 157 b(z0.imag()),
Chris@16 158 c(z1.real()),
Chris@16 159 d(z1.imag())
Chris@16 160 {
Chris@16 161 // nothing to do!
Chris@16 162 }
Chris@16 163
Chris@16 164
Chris@16 165 // UNtemplated copy constructor
Chris@16 166 // (this is taken care of by the compiler itself)
Chris@16 167
Chris@16 168
Chris@16 169 // templated copy constructor
Chris@16 170
Chris@16 171 template<typename X>
Chris@16 172 explicit quaternion(quaternion<X> const & a_recopier)
Chris@16 173 : a(static_cast<T>(a_recopier.R_component_1())),
Chris@16 174 b(static_cast<T>(a_recopier.R_component_2())),
Chris@16 175 c(static_cast<T>(a_recopier.R_component_3())),
Chris@16 176 d(static_cast<T>(a_recopier.R_component_4()))
Chris@16 177 {
Chris@16 178 // nothing to do!
Chris@16 179 }
Chris@16 180
Chris@16 181
Chris@16 182 // destructor
Chris@16 183 // (this is taken care of by the compiler itself)
Chris@16 184
Chris@16 185
Chris@16 186 // accessors
Chris@16 187 //
Chris@16 188 // Note: Like complex number, quaternions do have a meaningful notion of "real part",
Chris@16 189 // but unlike them there is no meaningful notion of "imaginary part".
Chris@16 190 // Instead there is an "unreal part" which itself is a quaternion, and usually
Chris@16 191 // nothing simpler (as opposed to the complex number case).
Chris@16 192 // However, for practicallity, there are accessors for the other components
Chris@16 193 // (these are necessary for the templated copy constructor, for instance).
Chris@16 194
Chris@16 195 BOOST_QUATERNION_ACCESSOR_GENERATOR(T)
Chris@16 196
Chris@16 197 // assignment operators
Chris@16 198
Chris@16 199 BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(T)
Chris@16 200
Chris@16 201 // other assignment-related operators
Chris@16 202 //
Chris@16 203 // NOTE: Quaternion multiplication is *NOT* commutative;
Chris@16 204 // symbolically, "q *= rhs;" means "q = q * rhs;"
Chris@16 205 // and "q /= rhs;" means "q = q * inverse_of(rhs);"
Chris@16 206
Chris@16 207 quaternion<T> & operator += (T const & rhs)
Chris@16 208 {
Chris@16 209 T at = a + rhs; // exception guard
Chris@16 210
Chris@16 211 a = at;
Chris@16 212
Chris@16 213 return(*this);
Chris@16 214 }
Chris@16 215
Chris@16 216
Chris@16 217 quaternion<T> & operator += (::std::complex<T> const & rhs)
Chris@16 218 {
Chris@16 219 T at = a + rhs.real(); // exception guard
Chris@16 220 T bt = b + rhs.imag(); // exception guard
Chris@16 221
Chris@16 222 a = at;
Chris@16 223 b = bt;
Chris@16 224
Chris@16 225 return(*this);
Chris@16 226 }
Chris@16 227
Chris@16 228
Chris@16 229 template<typename X>
Chris@16 230 quaternion<T> & operator += (quaternion<X> const & rhs)
Chris@16 231 {
Chris@16 232 T at = a + static_cast<T>(rhs.R_component_1()); // exception guard
Chris@16 233 T bt = b + static_cast<T>(rhs.R_component_2()); // exception guard
Chris@16 234 T ct = c + static_cast<T>(rhs.R_component_3()); // exception guard
Chris@16 235 T dt = d + static_cast<T>(rhs.R_component_4()); // exception guard
Chris@16 236
Chris@16 237 a = at;
Chris@16 238 b = bt;
Chris@16 239 c = ct;
Chris@16 240 d = dt;
Chris@16 241
Chris@16 242 return(*this);
Chris@16 243 }
Chris@16 244
Chris@16 245
Chris@16 246
Chris@16 247 quaternion<T> & operator -= (T const & rhs)
Chris@16 248 {
Chris@16 249 T at = a - rhs; // exception guard
Chris@16 250
Chris@16 251 a = at;
Chris@16 252
Chris@16 253 return(*this);
Chris@16 254 }
Chris@16 255
Chris@16 256
Chris@16 257 quaternion<T> & operator -= (::std::complex<T> const & rhs)
Chris@16 258 {
Chris@16 259 T at = a - rhs.real(); // exception guard
Chris@16 260 T bt = b - rhs.imag(); // exception guard
Chris@16 261
Chris@16 262 a = at;
Chris@16 263 b = bt;
Chris@16 264
Chris@16 265 return(*this);
Chris@16 266 }
Chris@16 267
Chris@16 268
Chris@16 269 template<typename X>
Chris@16 270 quaternion<T> & operator -= (quaternion<X> const & rhs)
Chris@16 271 {
Chris@16 272 T at = a - static_cast<T>(rhs.R_component_1()); // exception guard
Chris@16 273 T bt = b - static_cast<T>(rhs.R_component_2()); // exception guard
Chris@16 274 T ct = c - static_cast<T>(rhs.R_component_3()); // exception guard
Chris@16 275 T dt = d - static_cast<T>(rhs.R_component_4()); // exception guard
Chris@16 276
Chris@16 277 a = at;
Chris@16 278 b = bt;
Chris@16 279 c = ct;
Chris@16 280 d = dt;
Chris@16 281
Chris@16 282 return(*this);
Chris@16 283 }
Chris@16 284
Chris@16 285
Chris@16 286 quaternion<T> & operator *= (T const & rhs)
Chris@16 287 {
Chris@16 288 T at = a * rhs; // exception guard
Chris@16 289 T bt = b * rhs; // exception guard
Chris@16 290 T ct = c * rhs; // exception guard
Chris@16 291 T dt = d * rhs; // exception guard
Chris@16 292
Chris@16 293 a = at;
Chris@16 294 b = bt;
Chris@16 295 c = ct;
Chris@16 296 d = dt;
Chris@16 297
Chris@16 298 return(*this);
Chris@16 299 }
Chris@16 300
Chris@16 301
Chris@16 302 quaternion<T> & operator *= (::std::complex<T> const & rhs)
Chris@16 303 {
Chris@16 304 T ar = rhs.real();
Chris@16 305 T br = rhs.imag();
Chris@16 306
Chris@16 307 T at = +a*ar-b*br;
Chris@16 308 T bt = +a*br+b*ar;
Chris@16 309 T ct = +c*ar+d*br;
Chris@16 310 T dt = -c*br+d*ar;
Chris@16 311
Chris@16 312 a = at;
Chris@16 313 b = bt;
Chris@16 314 c = ct;
Chris@16 315 d = dt;
Chris@16 316
Chris@16 317 return(*this);
Chris@16 318 }
Chris@16 319
Chris@16 320
Chris@16 321 template<typename X>
Chris@16 322 quaternion<T> & operator *= (quaternion<X> const & rhs)
Chris@16 323 {
Chris@16 324 T ar = static_cast<T>(rhs.R_component_1());
Chris@16 325 T br = static_cast<T>(rhs.R_component_2());
Chris@16 326 T cr = static_cast<T>(rhs.R_component_3());
Chris@16 327 T dr = static_cast<T>(rhs.R_component_4());
Chris@16 328
Chris@16 329 T at = +a*ar-b*br-c*cr-d*dr;
Chris@16 330 T bt = +a*br+b*ar+c*dr-d*cr; //(a*br+ar*b)+(c*dr-cr*d);
Chris@16 331 T ct = +a*cr-b*dr+c*ar+d*br; //(a*cr+ar*c)+(d*br-dr*b);
Chris@16 332 T dt = +a*dr+b*cr-c*br+d*ar; //(a*dr+ar*d)+(b*cr-br*c);
Chris@16 333
Chris@16 334 a = at;
Chris@16 335 b = bt;
Chris@16 336 c = ct;
Chris@16 337 d = dt;
Chris@16 338
Chris@16 339 return(*this);
Chris@16 340 }
Chris@16 341
Chris@16 342
Chris@16 343
Chris@16 344 quaternion<T> & operator /= (T const & rhs)
Chris@16 345 {
Chris@16 346 T at = a / rhs; // exception guard
Chris@16 347 T bt = b / rhs; // exception guard
Chris@16 348 T ct = c / rhs; // exception guard
Chris@16 349 T dt = d / rhs; // exception guard
Chris@16 350
Chris@16 351 a = at;
Chris@16 352 b = bt;
Chris@16 353 c = ct;
Chris@16 354 d = dt;
Chris@16 355
Chris@16 356 return(*this);
Chris@16 357 }
Chris@16 358
Chris@16 359
Chris@16 360 quaternion<T> & operator /= (::std::complex<T> const & rhs)
Chris@16 361 {
Chris@16 362 T ar = rhs.real();
Chris@16 363 T br = rhs.imag();
Chris@16 364
Chris@16 365 T denominator = ar*ar+br*br;
Chris@16 366
Chris@16 367 T at = (+a*ar+b*br)/denominator; //(a*ar+b*br)/denominator;
Chris@16 368 T bt = (-a*br+b*ar)/denominator; //(ar*b-a*br)/denominator;
Chris@16 369 T ct = (+c*ar-d*br)/denominator; //(ar*c-d*br)/denominator;
Chris@16 370 T dt = (+c*br+d*ar)/denominator; //(ar*d+br*c)/denominator;
Chris@16 371
Chris@16 372 a = at;
Chris@16 373 b = bt;
Chris@16 374 c = ct;
Chris@16 375 d = dt;
Chris@16 376
Chris@16 377 return(*this);
Chris@16 378 }
Chris@16 379
Chris@16 380
Chris@16 381 template<typename X>
Chris@16 382 quaternion<T> & operator /= (quaternion<X> const & rhs)
Chris@16 383 {
Chris@16 384 T ar = static_cast<T>(rhs.R_component_1());
Chris@16 385 T br = static_cast<T>(rhs.R_component_2());
Chris@16 386 T cr = static_cast<T>(rhs.R_component_3());
Chris@16 387 T dr = static_cast<T>(rhs.R_component_4());
Chris@16 388
Chris@16 389 T denominator = ar*ar+br*br+cr*cr+dr*dr;
Chris@16 390
Chris@16 391 T at = (+a*ar+b*br+c*cr+d*dr)/denominator; //(a*ar+b*br+c*cr+d*dr)/denominator;
Chris@16 392 T bt = (-a*br+b*ar-c*dr+d*cr)/denominator; //((ar*b-a*br)+(cr*d-c*dr))/denominator;
Chris@16 393 T ct = (-a*cr+b*dr+c*ar-d*br)/denominator; //((ar*c-a*cr)+(dr*b-d*br))/denominator;
Chris@16 394 T dt = (-a*dr-b*cr+c*br+d*ar)/denominator; //((ar*d-a*dr)+(br*c-b*cr))/denominator;
Chris@16 395
Chris@16 396 a = at;
Chris@16 397 b = bt;
Chris@16 398 c = ct;
Chris@16 399 d = dt;
Chris@16 400
Chris@16 401 return(*this);
Chris@16 402 }
Chris@16 403
Chris@16 404
Chris@16 405 protected:
Chris@16 406
Chris@16 407 BOOST_QUATERNION_MEMBER_DATA_GENERATOR(T)
Chris@16 408
Chris@16 409
Chris@16 410 private:
Chris@16 411
Chris@16 412 };
Chris@16 413
Chris@16 414
Chris@16 415 // declaration of quaternion specialization
Chris@16 416
Chris@16 417 template<> class quaternion<float>;
Chris@16 418 template<> class quaternion<double>;
Chris@16 419 template<> class quaternion<long double>;
Chris@16 420
Chris@16 421
Chris@16 422 // helper templates for converting copy constructors (declaration)
Chris@16 423
Chris@16 424 namespace detail
Chris@16 425 {
Chris@16 426
Chris@16 427 template< typename T,
Chris@16 428 typename U
Chris@16 429 >
Chris@16 430 quaternion<T> quaternion_type_converter(quaternion<U> const & rhs);
Chris@16 431 }
Chris@16 432
Chris@16 433
Chris@16 434 // implementation of quaternion specialization
Chris@16 435
Chris@16 436
Chris@16 437 #define BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(type) \
Chris@16 438 explicit quaternion( type const & requested_a = static_cast<type>(0), \
Chris@16 439 type const & requested_b = static_cast<type>(0), \
Chris@16 440 type const & requested_c = static_cast<type>(0), \
Chris@16 441 type const & requested_d = static_cast<type>(0)) \
Chris@16 442 : a(requested_a), \
Chris@16 443 b(requested_b), \
Chris@16 444 c(requested_c), \
Chris@16 445 d(requested_d) \
Chris@16 446 { \
Chris@16 447 } \
Chris@16 448 \
Chris@16 449 explicit quaternion( ::std::complex<type> const & z0, \
Chris@16 450 ::std::complex<type> const & z1 = ::std::complex<type>()) \
Chris@16 451 : a(z0.real()), \
Chris@16 452 b(z0.imag()), \
Chris@16 453 c(z1.real()), \
Chris@16 454 d(z1.imag()) \
Chris@16 455 { \
Chris@16 456 }
Chris@16 457
Chris@16 458
Chris@16 459 #define BOOST_QUATERNION_MEMBER_ADD_GENERATOR_1(type) \
Chris@16 460 quaternion<type> & operator += (type const & rhs) \
Chris@16 461 { \
Chris@16 462 a += rhs; \
Chris@16 463 \
Chris@16 464 return(*this); \
Chris@16 465 }
Chris@16 466
Chris@16 467 #define BOOST_QUATERNION_MEMBER_ADD_GENERATOR_2(type) \
Chris@16 468 quaternion<type> & operator += (::std::complex<type> const & rhs) \
Chris@16 469 { \
Chris@16 470 a += rhs.real(); \
Chris@16 471 b += rhs.imag(); \
Chris@16 472 \
Chris@16 473 return(*this); \
Chris@16 474 }
Chris@16 475
Chris@16 476 #define BOOST_QUATERNION_MEMBER_ADD_GENERATOR_3(type) \
Chris@16 477 template<typename X> \
Chris@16 478 quaternion<type> & operator += (quaternion<X> const & rhs) \
Chris@16 479 { \
Chris@16 480 a += static_cast<type>(rhs.R_component_1()); \
Chris@16 481 b += static_cast<type>(rhs.R_component_2()); \
Chris@16 482 c += static_cast<type>(rhs.R_component_3()); \
Chris@16 483 d += static_cast<type>(rhs.R_component_4()); \
Chris@16 484 \
Chris@16 485 return(*this); \
Chris@16 486 }
Chris@16 487
Chris@16 488 #define BOOST_QUATERNION_MEMBER_SUB_GENERATOR_1(type) \
Chris@16 489 quaternion<type> & operator -= (type const & rhs) \
Chris@16 490 { \
Chris@16 491 a -= rhs; \
Chris@16 492 \
Chris@16 493 return(*this); \
Chris@16 494 }
Chris@16 495
Chris@16 496 #define BOOST_QUATERNION_MEMBER_SUB_GENERATOR_2(type) \
Chris@16 497 quaternion<type> & operator -= (::std::complex<type> const & rhs) \
Chris@16 498 { \
Chris@16 499 a -= rhs.real(); \
Chris@16 500 b -= rhs.imag(); \
Chris@16 501 \
Chris@16 502 return(*this); \
Chris@16 503 }
Chris@16 504
Chris@16 505 #define BOOST_QUATERNION_MEMBER_SUB_GENERATOR_3(type) \
Chris@16 506 template<typename X> \
Chris@16 507 quaternion<type> & operator -= (quaternion<X> const & rhs) \
Chris@16 508 { \
Chris@16 509 a -= static_cast<type>(rhs.R_component_1()); \
Chris@16 510 b -= static_cast<type>(rhs.R_component_2()); \
Chris@16 511 c -= static_cast<type>(rhs.R_component_3()); \
Chris@16 512 d -= static_cast<type>(rhs.R_component_4()); \
Chris@16 513 \
Chris@16 514 return(*this); \
Chris@16 515 }
Chris@16 516
Chris@16 517 #define BOOST_QUATERNION_MEMBER_MUL_GENERATOR_1(type) \
Chris@16 518 quaternion<type> & operator *= (type const & rhs) \
Chris@16 519 { \
Chris@16 520 a *= rhs; \
Chris@16 521 b *= rhs; \
Chris@16 522 c *= rhs; \
Chris@16 523 d *= rhs; \
Chris@16 524 \
Chris@16 525 return(*this); \
Chris@16 526 }
Chris@16 527
Chris@16 528 #define BOOST_QUATERNION_MEMBER_MUL_GENERATOR_2(type) \
Chris@16 529 quaternion<type> & operator *= (::std::complex<type> const & rhs) \
Chris@16 530 { \
Chris@16 531 type ar = rhs.real(); \
Chris@16 532 type br = rhs.imag(); \
Chris@16 533 \
Chris@16 534 type at = +a*ar-b*br; \
Chris@16 535 type bt = +a*br+b*ar; \
Chris@16 536 type ct = +c*ar+d*br; \
Chris@16 537 type dt = -c*br+d*ar; \
Chris@16 538 \
Chris@16 539 a = at; \
Chris@16 540 b = bt; \
Chris@16 541 c = ct; \
Chris@16 542 d = dt; \
Chris@16 543 \
Chris@16 544 return(*this); \
Chris@16 545 }
Chris@16 546
Chris@16 547 #define BOOST_QUATERNION_MEMBER_MUL_GENERATOR_3(type) \
Chris@16 548 template<typename X> \
Chris@16 549 quaternion<type> & operator *= (quaternion<X> const & rhs) \
Chris@16 550 { \
Chris@16 551 type ar = static_cast<type>(rhs.R_component_1()); \
Chris@16 552 type br = static_cast<type>(rhs.R_component_2()); \
Chris@16 553 type cr = static_cast<type>(rhs.R_component_3()); \
Chris@16 554 type dr = static_cast<type>(rhs.R_component_4()); \
Chris@16 555 \
Chris@16 556 type at = +a*ar-b*br-c*cr-d*dr; \
Chris@16 557 type bt = +a*br+b*ar+c*dr-d*cr; \
Chris@16 558 type ct = +a*cr-b*dr+c*ar+d*br; \
Chris@16 559 type dt = +a*dr+b*cr-c*br+d*ar; \
Chris@16 560 \
Chris@16 561 a = at; \
Chris@16 562 b = bt; \
Chris@16 563 c = ct; \
Chris@16 564 d = dt; \
Chris@16 565 \
Chris@16 566 return(*this); \
Chris@16 567 }
Chris@16 568
Chris@16 569 // There is quite a lot of repetition in the code below. This is intentional.
Chris@16 570 // The last conditional block is the normal form, and the others merely
Chris@16 571 // consist of workarounds for various compiler deficiencies. Hopefuly, when
Chris@16 572 // more compilers are conformant and we can retire support for those that are
Chris@16 573 // not, we will be able to remove the clutter. This is makes the situation
Chris@16 574 // (painfully) explicit.
Chris@16 575
Chris@16 576 #define BOOST_QUATERNION_MEMBER_DIV_GENERATOR_1(type) \
Chris@16 577 quaternion<type> & operator /= (type const & rhs) \
Chris@16 578 { \
Chris@16 579 a /= rhs; \
Chris@16 580 b /= rhs; \
Chris@16 581 c /= rhs; \
Chris@16 582 d /= rhs; \
Chris@16 583 \
Chris@16 584 return(*this); \
Chris@16 585 }
Chris@16 586
Chris@101 587 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
Chris@16 588 #define BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type) \
Chris@16 589 quaternion<type> & operator /= (::std::complex<type> const & rhs) \
Chris@16 590 { \
Chris@16 591 using ::std::valarray; \
Chris@16 592 using ::std::abs; \
Chris@16 593 \
Chris@16 594 valarray<type> tr(2); \
Chris@16 595 \
Chris@16 596 tr[0] = rhs.real(); \
Chris@16 597 tr[1] = rhs.imag(); \
Chris@16 598 \
Chris@16 599 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
Chris@16 600 \
Chris@16 601 tr *= mixam; \
Chris@16 602 \
Chris@16 603 valarray<type> tt(4); \
Chris@16 604 \
Chris@16 605 tt[0] = +a*tr[0]+b*tr[1]; \
Chris@16 606 tt[1] = -a*tr[1]+b*tr[0]; \
Chris@16 607 tt[2] = +c*tr[0]-d*tr[1]; \
Chris@16 608 tt[3] = +c*tr[1]+d*tr[0]; \
Chris@16 609 \
Chris@16 610 tr *= tr; \
Chris@16 611 \
Chris@16 612 tt *= (mixam/tr.sum()); \
Chris@16 613 \
Chris@16 614 a = tt[0]; \
Chris@16 615 b = tt[1]; \
Chris@16 616 c = tt[2]; \
Chris@16 617 d = tt[3]; \
Chris@16 618 \
Chris@16 619 return(*this); \
Chris@16 620 }
Chris@16 621 #else
Chris@16 622 #define BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type) \
Chris@16 623 quaternion<type> & operator /= (::std::complex<type> const & rhs) \
Chris@16 624 { \
Chris@16 625 using ::std::valarray; \
Chris@16 626 \
Chris@16 627 valarray<type> tr(2); \
Chris@16 628 \
Chris@16 629 tr[0] = rhs.real(); \
Chris@16 630 tr[1] = rhs.imag(); \
Chris@16 631 \
Chris@16 632 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
Chris@16 633 \
Chris@16 634 tr *= mixam; \
Chris@16 635 \
Chris@16 636 valarray<type> tt(4); \
Chris@16 637 \
Chris@16 638 tt[0] = +a*tr[0]+b*tr[1]; \
Chris@16 639 tt[1] = -a*tr[1]+b*tr[0]; \
Chris@16 640 tt[2] = +c*tr[0]-d*tr[1]; \
Chris@16 641 tt[3] = +c*tr[1]+d*tr[0]; \
Chris@16 642 \
Chris@16 643 tr *= tr; \
Chris@16 644 \
Chris@16 645 tt *= (mixam/tr.sum()); \
Chris@16 646 \
Chris@16 647 a = tt[0]; \
Chris@16 648 b = tt[1]; \
Chris@16 649 c = tt[2]; \
Chris@16 650 d = tt[3]; \
Chris@16 651 \
Chris@16 652 return(*this); \
Chris@16 653 }
Chris@101 654 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
Chris@16 655
Chris@101 656 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
Chris@16 657 #define BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type) \
Chris@16 658 template<typename X> \
Chris@16 659 quaternion<type> & operator /= (quaternion<X> const & rhs) \
Chris@16 660 { \
Chris@16 661 using ::std::valarray; \
Chris@16 662 using ::std::abs; \
Chris@16 663 \
Chris@16 664 valarray<type> tr(4); \
Chris@16 665 \
Chris@16 666 tr[0] = static_cast<type>(rhs.R_component_1()); \
Chris@16 667 tr[1] = static_cast<type>(rhs.R_component_2()); \
Chris@16 668 tr[2] = static_cast<type>(rhs.R_component_3()); \
Chris@16 669 tr[3] = static_cast<type>(rhs.R_component_4()); \
Chris@16 670 \
Chris@16 671 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
Chris@16 672 \
Chris@16 673 tr *= mixam; \
Chris@16 674 \
Chris@16 675 valarray<type> tt(4); \
Chris@16 676 \
Chris@16 677 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \
Chris@16 678 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \
Chris@16 679 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \
Chris@16 680 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \
Chris@16 681 \
Chris@16 682 tr *= tr; \
Chris@16 683 \
Chris@16 684 tt *= (mixam/tr.sum()); \
Chris@16 685 \
Chris@16 686 a = tt[0]; \
Chris@16 687 b = tt[1]; \
Chris@16 688 c = tt[2]; \
Chris@16 689 d = tt[3]; \
Chris@16 690 \
Chris@16 691 return(*this); \
Chris@16 692 }
Chris@16 693 #else
Chris@16 694 #define BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type) \
Chris@16 695 template<typename X> \
Chris@16 696 quaternion<type> & operator /= (quaternion<X> const & rhs) \
Chris@16 697 { \
Chris@16 698 using ::std::valarray; \
Chris@16 699 \
Chris@16 700 valarray<type> tr(4); \
Chris@16 701 \
Chris@16 702 tr[0] = static_cast<type>(rhs.R_component_1()); \
Chris@16 703 tr[1] = static_cast<type>(rhs.R_component_2()); \
Chris@16 704 tr[2] = static_cast<type>(rhs.R_component_3()); \
Chris@16 705 tr[3] = static_cast<type>(rhs.R_component_4()); \
Chris@16 706 \
Chris@16 707 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
Chris@16 708 \
Chris@16 709 tr *= mixam; \
Chris@16 710 \
Chris@16 711 valarray<type> tt(4); \
Chris@16 712 \
Chris@16 713 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \
Chris@16 714 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \
Chris@16 715 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \
Chris@16 716 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \
Chris@16 717 \
Chris@16 718 tr *= tr; \
Chris@16 719 \
Chris@16 720 tt *= (mixam/tr.sum()); \
Chris@16 721 \
Chris@16 722 a = tt[0]; \
Chris@16 723 b = tt[1]; \
Chris@16 724 c = tt[2]; \
Chris@16 725 d = tt[3]; \
Chris@16 726 \
Chris@16 727 return(*this); \
Chris@16 728 }
Chris@101 729 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
Chris@16 730
Chris@16 731 #define BOOST_QUATERNION_MEMBER_ADD_GENERATOR(type) \
Chris@16 732 BOOST_QUATERNION_MEMBER_ADD_GENERATOR_1(type) \
Chris@16 733 BOOST_QUATERNION_MEMBER_ADD_GENERATOR_2(type) \
Chris@16 734 BOOST_QUATERNION_MEMBER_ADD_GENERATOR_3(type)
Chris@16 735
Chris@16 736 #define BOOST_QUATERNION_MEMBER_SUB_GENERATOR(type) \
Chris@16 737 BOOST_QUATERNION_MEMBER_SUB_GENERATOR_1(type) \
Chris@16 738 BOOST_QUATERNION_MEMBER_SUB_GENERATOR_2(type) \
Chris@16 739 BOOST_QUATERNION_MEMBER_SUB_GENERATOR_3(type)
Chris@16 740
Chris@16 741 #define BOOST_QUATERNION_MEMBER_MUL_GENERATOR(type) \
Chris@16 742 BOOST_QUATERNION_MEMBER_MUL_GENERATOR_1(type) \
Chris@16 743 BOOST_QUATERNION_MEMBER_MUL_GENERATOR_2(type) \
Chris@16 744 BOOST_QUATERNION_MEMBER_MUL_GENERATOR_3(type)
Chris@16 745
Chris@16 746 #define BOOST_QUATERNION_MEMBER_DIV_GENERATOR(type) \
Chris@16 747 BOOST_QUATERNION_MEMBER_DIV_GENERATOR_1(type) \
Chris@16 748 BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2(type) \
Chris@16 749 BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3(type)
Chris@16 750
Chris@16 751 #define BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(type) \
Chris@16 752 BOOST_QUATERNION_MEMBER_ADD_GENERATOR(type) \
Chris@16 753 BOOST_QUATERNION_MEMBER_SUB_GENERATOR(type) \
Chris@16 754 BOOST_QUATERNION_MEMBER_MUL_GENERATOR(type) \
Chris@16 755 BOOST_QUATERNION_MEMBER_DIV_GENERATOR(type)
Chris@16 756
Chris@16 757
Chris@16 758 template<>
Chris@16 759 class quaternion<float>
Chris@16 760 {
Chris@16 761 public:
Chris@16 762
Chris@16 763 typedef float value_type;
Chris@16 764
Chris@16 765 BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(float)
Chris@16 766
Chris@16 767 // UNtemplated copy constructor
Chris@16 768 // (this is taken care of by the compiler itself)
Chris@16 769
Chris@16 770 // explicit copy constructors (precision-loosing converters)
Chris@16 771
Chris@16 772 explicit quaternion(quaternion<double> const & a_recopier)
Chris@16 773 {
Chris@16 774 *this = detail::quaternion_type_converter<float, double>(a_recopier);
Chris@16 775 }
Chris@16 776
Chris@16 777 explicit quaternion(quaternion<long double> const & a_recopier)
Chris@16 778 {
Chris@16 779 *this = detail::quaternion_type_converter<float, long double>(a_recopier);
Chris@16 780 }
Chris@16 781
Chris@16 782 // destructor
Chris@16 783 // (this is taken care of by the compiler itself)
Chris@16 784
Chris@16 785 // accessors
Chris@16 786 //
Chris@16 787 // Note: Like complex number, quaternions do have a meaningful notion of "real part",
Chris@16 788 // but unlike them there is no meaningful notion of "imaginary part".
Chris@16 789 // Instead there is an "unreal part" which itself is a quaternion, and usually
Chris@16 790 // nothing simpler (as opposed to the complex number case).
Chris@16 791 // However, for practicallity, there are accessors for the other components
Chris@16 792 // (these are necessary for the templated copy constructor, for instance).
Chris@16 793
Chris@16 794 BOOST_QUATERNION_ACCESSOR_GENERATOR(float)
Chris@16 795
Chris@16 796 // assignment operators
Chris@16 797
Chris@16 798 BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(float)
Chris@16 799
Chris@16 800 // other assignment-related operators
Chris@16 801 //
Chris@16 802 // NOTE: Quaternion multiplication is *NOT* commutative;
Chris@16 803 // symbolically, "q *= rhs;" means "q = q * rhs;"
Chris@16 804 // and "q /= rhs;" means "q = q * inverse_of(rhs);"
Chris@16 805
Chris@16 806 BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(float)
Chris@16 807
Chris@16 808
Chris@16 809 protected:
Chris@16 810
Chris@16 811 BOOST_QUATERNION_MEMBER_DATA_GENERATOR(float)
Chris@16 812
Chris@16 813
Chris@16 814 private:
Chris@16 815
Chris@16 816 };
Chris@16 817
Chris@16 818
Chris@16 819 template<>
Chris@16 820 class quaternion<double>
Chris@16 821 {
Chris@16 822 public:
Chris@16 823
Chris@16 824 typedef double value_type;
Chris@16 825
Chris@16 826 BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(double)
Chris@16 827
Chris@16 828 // UNtemplated copy constructor
Chris@16 829 // (this is taken care of by the compiler itself)
Chris@16 830
Chris@16 831 // converting copy constructor
Chris@16 832
Chris@16 833 explicit quaternion(quaternion<float> const & a_recopier)
Chris@16 834 {
Chris@16 835 *this = detail::quaternion_type_converter<double, float>(a_recopier);
Chris@16 836 }
Chris@16 837
Chris@16 838 // explicit copy constructors (precision-loosing converters)
Chris@16 839
Chris@16 840 explicit quaternion(quaternion<long double> const & a_recopier)
Chris@16 841 {
Chris@16 842 *this = detail::quaternion_type_converter<double, long double>(a_recopier);
Chris@16 843 }
Chris@16 844
Chris@16 845 // destructor
Chris@16 846 // (this is taken care of by the compiler itself)
Chris@16 847
Chris@16 848 // accessors
Chris@16 849 //
Chris@16 850 // Note: Like complex number, quaternions do have a meaningful notion of "real part",
Chris@16 851 // but unlike them there is no meaningful notion of "imaginary part".
Chris@16 852 // Instead there is an "unreal part" which itself is a quaternion, and usually
Chris@16 853 // nothing simpler (as opposed to the complex number case).
Chris@16 854 // However, for practicallity, there are accessors for the other components
Chris@16 855 // (these are necessary for the templated copy constructor, for instance).
Chris@16 856
Chris@16 857 BOOST_QUATERNION_ACCESSOR_GENERATOR(double)
Chris@16 858
Chris@16 859 // assignment operators
Chris@16 860
Chris@16 861 BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(double)
Chris@16 862
Chris@16 863 // other assignment-related operators
Chris@16 864 //
Chris@16 865 // NOTE: Quaternion multiplication is *NOT* commutative;
Chris@16 866 // symbolically, "q *= rhs;" means "q = q * rhs;"
Chris@16 867 // and "q /= rhs;" means "q = q * inverse_of(rhs);"
Chris@16 868
Chris@16 869 BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(double)
Chris@16 870
Chris@16 871
Chris@16 872 protected:
Chris@16 873
Chris@16 874 BOOST_QUATERNION_MEMBER_DATA_GENERATOR(double)
Chris@16 875
Chris@16 876
Chris@16 877 private:
Chris@16 878
Chris@16 879 };
Chris@16 880
Chris@16 881
Chris@16 882 template<>
Chris@16 883 class quaternion<long double>
Chris@16 884 {
Chris@16 885 public:
Chris@16 886
Chris@16 887 typedef long double value_type;
Chris@16 888
Chris@16 889 BOOST_QUATERNION_CONSTRUCTOR_GENERATOR(long double)
Chris@16 890
Chris@16 891 // UNtemplated copy constructor
Chris@16 892 // (this is taken care of by the compiler itself)
Chris@16 893
Chris@16 894 // converting copy constructors
Chris@16 895
Chris@16 896 explicit quaternion(quaternion<float> const & a_recopier)
Chris@16 897 {
Chris@16 898 *this = detail::quaternion_type_converter<long double, float>(a_recopier);
Chris@16 899 }
Chris@16 900
Chris@16 901 explicit quaternion(quaternion<double> const & a_recopier)
Chris@16 902 {
Chris@16 903 *this = detail::quaternion_type_converter<long double, double>(a_recopier);
Chris@16 904 }
Chris@16 905
Chris@16 906 // destructor
Chris@16 907 // (this is taken care of by the compiler itself)
Chris@16 908
Chris@16 909 // accessors
Chris@16 910 //
Chris@16 911 // Note: Like complex number, quaternions do have a meaningful notion of "real part",
Chris@16 912 // but unlike them there is no meaningful notion of "imaginary part".
Chris@16 913 // Instead there is an "unreal part" which itself is a quaternion, and usually
Chris@16 914 // nothing simpler (as opposed to the complex number case).
Chris@16 915 // However, for practicallity, there are accessors for the other components
Chris@16 916 // (these are necessary for the templated copy constructor, for instance).
Chris@16 917
Chris@16 918 BOOST_QUATERNION_ACCESSOR_GENERATOR(long double)
Chris@16 919
Chris@16 920 // assignment operators
Chris@16 921
Chris@16 922 BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR(long double)
Chris@16 923
Chris@16 924 // other assignment-related operators
Chris@16 925 //
Chris@16 926 // NOTE: Quaternion multiplication is *NOT* commutative;
Chris@16 927 // symbolically, "q *= rhs;" means "q = q * rhs;"
Chris@16 928 // and "q /= rhs;" means "q = q * inverse_of(rhs);"
Chris@16 929
Chris@16 930 BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR(long double)
Chris@16 931
Chris@16 932
Chris@16 933 protected:
Chris@16 934
Chris@16 935 BOOST_QUATERNION_MEMBER_DATA_GENERATOR(long double)
Chris@16 936
Chris@16 937
Chris@16 938 private:
Chris@16 939
Chris@16 940 };
Chris@16 941
Chris@16 942
Chris@16 943 #undef BOOST_QUATERNION_MEMBER_ALGEBRAIC_GENERATOR
Chris@16 944 #undef BOOST_QUATERNION_MEMBER_ADD_GENERATOR
Chris@16 945 #undef BOOST_QUATERNION_MEMBER_SUB_GENERATOR
Chris@16 946 #undef BOOST_QUATERNION_MEMBER_MUL_GENERATOR
Chris@16 947 #undef BOOST_QUATERNION_MEMBER_DIV_GENERATOR
Chris@16 948 #undef BOOST_QUATERNION_MEMBER_ADD_GENERATOR_1
Chris@16 949 #undef BOOST_QUATERNION_MEMBER_ADD_GENERATOR_2
Chris@16 950 #undef BOOST_QUATERNION_MEMBER_ADD_GENERATOR_3
Chris@16 951 #undef BOOST_QUATERNION_MEMBER_SUB_GENERATOR_1
Chris@16 952 #undef BOOST_QUATERNION_MEMBER_SUB_GENERATOR_2
Chris@16 953 #undef BOOST_QUATERNION_MEMBER_SUB_GENERATOR_3
Chris@16 954 #undef BOOST_QUATERNION_MEMBER_MUL_GENERATOR_1
Chris@16 955 #undef BOOST_QUATERNION_MEMBER_MUL_GENERATOR_2
Chris@16 956 #undef BOOST_QUATERNION_MEMBER_MUL_GENERATOR_3
Chris@16 957 #undef BOOST_QUATERNION_MEMBER_DIV_GENERATOR_1
Chris@16 958 #undef BOOST_QUATERNION_MEMBER_DIV_GENERATOR_2
Chris@16 959 #undef BOOST_QUATERNION_MEMBER_DIV_GENERATOR_3
Chris@16 960
Chris@16 961 #undef BOOST_QUATERNION_CONSTRUCTOR_GENERATOR
Chris@16 962
Chris@16 963
Chris@16 964 #undef BOOST_QUATERNION_MEMBER_ASSIGNMENT_GENERATOR
Chris@16 965
Chris@16 966 #undef BOOST_QUATERNION_MEMBER_DATA_GENERATOR
Chris@16 967
Chris@16 968 #undef BOOST_QUATERNION_ACCESSOR_GENERATOR
Chris@16 969
Chris@16 970
Chris@16 971 // operators
Chris@16 972
Chris@16 973 #define BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op) \
Chris@16 974 { \
Chris@16 975 quaternion<T> res(lhs); \
Chris@16 976 res op##= rhs; \
Chris@16 977 return(res); \
Chris@16 978 }
Chris@16 979
Chris@16 980 #define BOOST_QUATERNION_OPERATOR_GENERATOR_1_L(op) \
Chris@16 981 template<typename T> \
Chris@16 982 inline quaternion<T> operator op (T const & lhs, quaternion<T> const & rhs) \
Chris@16 983 BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op)
Chris@16 984
Chris@16 985 #define BOOST_QUATERNION_OPERATOR_GENERATOR_1_R(op) \
Chris@16 986 template<typename T> \
Chris@16 987 inline quaternion<T> operator op (quaternion<T> const & lhs, T const & rhs) \
Chris@16 988 BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op)
Chris@16 989
Chris@16 990 #define BOOST_QUATERNION_OPERATOR_GENERATOR_2_L(op) \
Chris@16 991 template<typename T> \
Chris@16 992 inline quaternion<T> operator op (::std::complex<T> const & lhs, quaternion<T> const & rhs) \
Chris@16 993 BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op)
Chris@16 994
Chris@16 995 #define BOOST_QUATERNION_OPERATOR_GENERATOR_2_R(op) \
Chris@16 996 template<typename T> \
Chris@16 997 inline quaternion<T> operator op (quaternion<T> const & lhs, ::std::complex<T> const & rhs) \
Chris@16 998 BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op)
Chris@16 999
Chris@16 1000 #define BOOST_QUATERNION_OPERATOR_GENERATOR_3(op) \
Chris@16 1001 template<typename T> \
Chris@16 1002 inline quaternion<T> operator op (quaternion<T> const & lhs, quaternion<T> const & rhs) \
Chris@16 1003 BOOST_QUATERNION_OPERATOR_GENERATOR_BODY(op)
Chris@16 1004
Chris@16 1005 #define BOOST_QUATERNION_OPERATOR_GENERATOR(op) \
Chris@16 1006 BOOST_QUATERNION_OPERATOR_GENERATOR_1_L(op) \
Chris@16 1007 BOOST_QUATERNION_OPERATOR_GENERATOR_1_R(op) \
Chris@16 1008 BOOST_QUATERNION_OPERATOR_GENERATOR_2_L(op) \
Chris@16 1009 BOOST_QUATERNION_OPERATOR_GENERATOR_2_R(op) \
Chris@16 1010 BOOST_QUATERNION_OPERATOR_GENERATOR_3(op)
Chris@16 1011
Chris@16 1012
Chris@16 1013 BOOST_QUATERNION_OPERATOR_GENERATOR(+)
Chris@16 1014 BOOST_QUATERNION_OPERATOR_GENERATOR(-)
Chris@16 1015 BOOST_QUATERNION_OPERATOR_GENERATOR(*)
Chris@16 1016 BOOST_QUATERNION_OPERATOR_GENERATOR(/)
Chris@16 1017
Chris@16 1018
Chris@16 1019 #undef BOOST_QUATERNION_OPERATOR_GENERATOR
Chris@16 1020
Chris@16 1021 #undef BOOST_QUATERNION_OPERATOR_GENERATOR_1_L
Chris@16 1022 #undef BOOST_QUATERNION_OPERATOR_GENERATOR_1_R
Chris@16 1023 #undef BOOST_QUATERNION_OPERATOR_GENERATOR_2_L
Chris@16 1024 #undef BOOST_QUATERNION_OPERATOR_GENERATOR_2_R
Chris@16 1025 #undef BOOST_QUATERNION_OPERATOR_GENERATOR_3
Chris@16 1026
Chris@16 1027 #undef BOOST_QUATERNION_OPERATOR_GENERATOR_BODY
Chris@16 1028
Chris@16 1029
Chris@16 1030 template<typename T>
Chris@16 1031 inline quaternion<T> operator + (quaternion<T> const & q)
Chris@16 1032 {
Chris@16 1033 return(q);
Chris@16 1034 }
Chris@16 1035
Chris@16 1036
Chris@16 1037 template<typename T>
Chris@16 1038 inline quaternion<T> operator - (quaternion<T> const & q)
Chris@16 1039 {
Chris@16 1040 return(quaternion<T>(-q.R_component_1(),-q.R_component_2(),-q.R_component_3(),-q.R_component_4()));
Chris@16 1041 }
Chris@16 1042
Chris@16 1043
Chris@16 1044 template<typename T>
Chris@16 1045 inline bool operator == (T const & lhs, quaternion<T> const & rhs)
Chris@16 1046 {
Chris@16 1047 return (
Chris@16 1048 (rhs.R_component_1() == lhs)&&
Chris@16 1049 (rhs.R_component_2() == static_cast<T>(0))&&
Chris@16 1050 (rhs.R_component_3() == static_cast<T>(0))&&
Chris@16 1051 (rhs.R_component_4() == static_cast<T>(0))
Chris@16 1052 );
Chris@16 1053 }
Chris@16 1054
Chris@16 1055
Chris@16 1056 template<typename T>
Chris@16 1057 inline bool operator == (quaternion<T> const & lhs, T const & rhs)
Chris@16 1058 {
Chris@16 1059 return (
Chris@16 1060 (lhs.R_component_1() == rhs)&&
Chris@16 1061 (lhs.R_component_2() == static_cast<T>(0))&&
Chris@16 1062 (lhs.R_component_3() == static_cast<T>(0))&&
Chris@16 1063 (lhs.R_component_4() == static_cast<T>(0))
Chris@16 1064 );
Chris@16 1065 }
Chris@16 1066
Chris@16 1067
Chris@16 1068 template<typename T>
Chris@16 1069 inline bool operator == (::std::complex<T> const & lhs, quaternion<T> const & rhs)
Chris@16 1070 {
Chris@16 1071 return (
Chris@16 1072 (rhs.R_component_1() == lhs.real())&&
Chris@16 1073 (rhs.R_component_2() == lhs.imag())&&
Chris@16 1074 (rhs.R_component_3() == static_cast<T>(0))&&
Chris@16 1075 (rhs.R_component_4() == static_cast<T>(0))
Chris@16 1076 );
Chris@16 1077 }
Chris@16 1078
Chris@16 1079
Chris@16 1080 template<typename T>
Chris@16 1081 inline bool operator == (quaternion<T> const & lhs, ::std::complex<T> const & rhs)
Chris@16 1082 {
Chris@16 1083 return (
Chris@16 1084 (lhs.R_component_1() == rhs.real())&&
Chris@16 1085 (lhs.R_component_2() == rhs.imag())&&
Chris@16 1086 (lhs.R_component_3() == static_cast<T>(0))&&
Chris@16 1087 (lhs.R_component_4() == static_cast<T>(0))
Chris@16 1088 );
Chris@16 1089 }
Chris@16 1090
Chris@16 1091
Chris@16 1092 template<typename T>
Chris@16 1093 inline bool operator == (quaternion<T> const & lhs, quaternion<T> const & rhs)
Chris@16 1094 {
Chris@16 1095 return (
Chris@16 1096 (rhs.R_component_1() == lhs.R_component_1())&&
Chris@16 1097 (rhs.R_component_2() == lhs.R_component_2())&&
Chris@16 1098 (rhs.R_component_3() == lhs.R_component_3())&&
Chris@16 1099 (rhs.R_component_4() == lhs.R_component_4())
Chris@16 1100 );
Chris@16 1101 }
Chris@16 1102
Chris@16 1103
Chris@16 1104 #define BOOST_QUATERNION_NOT_EQUAL_GENERATOR \
Chris@16 1105 { \
Chris@16 1106 return(!(lhs == rhs)); \
Chris@16 1107 }
Chris@16 1108
Chris@16 1109 template<typename T>
Chris@16 1110 inline bool operator != (T const & lhs, quaternion<T> const & rhs)
Chris@16 1111 BOOST_QUATERNION_NOT_EQUAL_GENERATOR
Chris@16 1112
Chris@16 1113 template<typename T>
Chris@16 1114 inline bool operator != (quaternion<T> const & lhs, T const & rhs)
Chris@16 1115 BOOST_QUATERNION_NOT_EQUAL_GENERATOR
Chris@16 1116
Chris@16 1117 template<typename T>
Chris@16 1118 inline bool operator != (::std::complex<T> const & lhs, quaternion<T> const & rhs)
Chris@16 1119 BOOST_QUATERNION_NOT_EQUAL_GENERATOR
Chris@16 1120
Chris@16 1121 template<typename T>
Chris@16 1122 inline bool operator != (quaternion<T> const & lhs, ::std::complex<T> const & rhs)
Chris@16 1123 BOOST_QUATERNION_NOT_EQUAL_GENERATOR
Chris@16 1124
Chris@16 1125 template<typename T>
Chris@16 1126 inline bool operator != (quaternion<T> const & lhs, quaternion<T> const & rhs)
Chris@16 1127 BOOST_QUATERNION_NOT_EQUAL_GENERATOR
Chris@16 1128
Chris@16 1129 #undef BOOST_QUATERNION_NOT_EQUAL_GENERATOR
Chris@16 1130
Chris@16 1131
Chris@16 1132 // Note: we allow the following formats, whith a, b, c, and d reals
Chris@16 1133 // a
Chris@16 1134 // (a), (a,b), (a,b,c), (a,b,c,d)
Chris@16 1135 // (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b),(c,d))
Chris@16 1136 template<typename T, typename charT, class traits>
Chris@16 1137 ::std::basic_istream<charT,traits> & operator >> ( ::std::basic_istream<charT,traits> & is,
Chris@16 1138 quaternion<T> & q)
Chris@16 1139 {
Chris@16 1140
Chris@16 1141 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1142 #else
Chris@16 1143 const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc());
Chris@16 1144 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1145
Chris@16 1146 T a = T();
Chris@16 1147 T b = T();
Chris@16 1148 T c = T();
Chris@16 1149 T d = T();
Chris@16 1150
Chris@16 1151 ::std::complex<T> u = ::std::complex<T>();
Chris@16 1152 ::std::complex<T> v = ::std::complex<T>();
Chris@16 1153
Chris@16 1154 charT ch = charT();
Chris@16 1155 char cc;
Chris@16 1156
Chris@16 1157 is >> ch; // get the first lexeme
Chris@16 1158
Chris@16 1159 if (!is.good()) goto finish;
Chris@16 1160
Chris@16 1161 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1162 cc = ch;
Chris@16 1163 #else
Chris@16 1164 cc = ct.narrow(ch, char());
Chris@16 1165 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1166
Chris@16 1167 if (cc == '(') // read "(", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
Chris@16 1168 {
Chris@16 1169 is >> ch; // get the second lexeme
Chris@16 1170
Chris@16 1171 if (!is.good()) goto finish;
Chris@16 1172
Chris@16 1173 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1174 cc = ch;
Chris@16 1175 #else
Chris@16 1176 cc = ct.narrow(ch, char());
Chris@16 1177 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1178
Chris@16 1179 if (cc == '(') // read "((", possible: ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
Chris@16 1180 {
Chris@16 1181 is.putback(ch);
Chris@16 1182
Chris@16 1183 is >> u; // we extract the first and second components
Chris@16 1184 a = u.real();
Chris@16 1185 b = u.imag();
Chris@16 1186
Chris@16 1187 if (!is.good()) goto finish;
Chris@16 1188
Chris@16 1189 is >> ch; // get the next lexeme
Chris@16 1190
Chris@16 1191 if (!is.good()) goto finish;
Chris@16 1192
Chris@16 1193 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1194 cc = ch;
Chris@16 1195 #else
Chris@16 1196 cc = ct.narrow(ch, char());
Chris@16 1197 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1198
Chris@16 1199 if (cc == ')') // format: ((a)) or ((a,b))
Chris@16 1200 {
Chris@16 1201 q = quaternion<T>(a,b);
Chris@16 1202 }
Chris@16 1203 else if (cc == ',') // read "((a)," or "((a,b),", possible: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,))
Chris@16 1204 {
Chris@16 1205 is >> v; // we extract the third and fourth components
Chris@16 1206 c = v.real();
Chris@16 1207 d = v.imag();
Chris@16 1208
Chris@16 1209 if (!is.good()) goto finish;
Chris@16 1210
Chris@16 1211 is >> ch; // get the last lexeme
Chris@16 1212
Chris@16 1213 if (!is.good()) goto finish;
Chris@16 1214
Chris@16 1215 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1216 cc = ch;
Chris@16 1217 #else
Chris@16 1218 cc = ct.narrow(ch, char());
Chris@16 1219 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1220
Chris@16 1221 if (cc == ')') // format: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,))
Chris@16 1222 {
Chris@16 1223 q = quaternion<T>(a,b,c,d);
Chris@16 1224 }
Chris@16 1225 else // error
Chris@16 1226 {
Chris@16 1227 is.setstate(::std::ios_base::failbit);
Chris@16 1228 }
Chris@16 1229 }
Chris@16 1230 else // error
Chris@16 1231 {
Chris@16 1232 is.setstate(::std::ios_base::failbit);
Chris@16 1233 }
Chris@16 1234 }
Chris@16 1235 else // read "(a", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d))
Chris@16 1236 {
Chris@16 1237 is.putback(ch);
Chris@16 1238
Chris@16 1239 is >> a; // we extract the first component
Chris@16 1240
Chris@16 1241 if (!is.good()) goto finish;
Chris@16 1242
Chris@16 1243 is >> ch; // get the third lexeme
Chris@16 1244
Chris@16 1245 if (!is.good()) goto finish;
Chris@16 1246
Chris@16 1247 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1248 cc = ch;
Chris@16 1249 #else
Chris@16 1250 cc = ct.narrow(ch, char());
Chris@16 1251 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1252
Chris@16 1253 if (cc == ')') // format: (a)
Chris@16 1254 {
Chris@16 1255 q = quaternion<T>(a);
Chris@16 1256 }
Chris@16 1257 else if (cc == ',') // read "(a,", possible: (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d))
Chris@16 1258 {
Chris@16 1259 is >> ch; // get the fourth lexeme
Chris@16 1260
Chris@16 1261 if (!is.good()) goto finish;
Chris@16 1262
Chris@16 1263 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1264 cc = ch;
Chris@16 1265 #else
Chris@16 1266 cc = ct.narrow(ch, char());
Chris@16 1267 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1268
Chris@16 1269 if (cc == '(') // read "(a,(", possible: (a,(c)), (a,(c,d))
Chris@16 1270 {
Chris@16 1271 is.putback(ch);
Chris@16 1272
Chris@16 1273 is >> v; // we extract the third and fourth component
Chris@16 1274
Chris@16 1275 c = v.real();
Chris@16 1276 d = v.imag();
Chris@16 1277
Chris@16 1278 if (!is.good()) goto finish;
Chris@16 1279
Chris@16 1280 is >> ch; // get the ninth lexeme
Chris@16 1281
Chris@16 1282 if (!is.good()) goto finish;
Chris@16 1283
Chris@16 1284 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1285 cc = ch;
Chris@16 1286 #else
Chris@16 1287 cc = ct.narrow(ch, char());
Chris@16 1288 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1289
Chris@16 1290 if (cc == ')') // format: (a,(c)) or (a,(c,d))
Chris@16 1291 {
Chris@16 1292 q = quaternion<T>(a,b,c,d);
Chris@16 1293 }
Chris@16 1294 else // error
Chris@16 1295 {
Chris@16 1296 is.setstate(::std::ios_base::failbit);
Chris@16 1297 }
Chris@16 1298 }
Chris@16 1299 else // read "(a,b", possible: (a,b), (a,b,c), (a,b,c,d)
Chris@16 1300 {
Chris@16 1301 is.putback(ch);
Chris@16 1302
Chris@16 1303 is >> b; // we extract the second component
Chris@16 1304
Chris@16 1305 if (!is.good()) goto finish;
Chris@16 1306
Chris@16 1307 is >> ch; // get the fifth lexeme
Chris@16 1308
Chris@16 1309 if (!is.good()) goto finish;
Chris@16 1310
Chris@16 1311 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1312 cc = ch;
Chris@16 1313 #else
Chris@16 1314 cc = ct.narrow(ch, char());
Chris@16 1315 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1316
Chris@16 1317 if (cc == ')') // format: (a,b)
Chris@16 1318 {
Chris@16 1319 q = quaternion<T>(a,b);
Chris@16 1320 }
Chris@16 1321 else if (cc == ',') // read "(a,b,", possible: (a,b,c), (a,b,c,d)
Chris@16 1322 {
Chris@16 1323 is >> c; // we extract the third component
Chris@16 1324
Chris@16 1325 if (!is.good()) goto finish;
Chris@16 1326
Chris@16 1327 is >> ch; // get the seventh lexeme
Chris@16 1328
Chris@16 1329 if (!is.good()) goto finish;
Chris@16 1330
Chris@16 1331 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1332 cc = ch;
Chris@16 1333 #else
Chris@16 1334 cc = ct.narrow(ch, char());
Chris@16 1335 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1336
Chris@16 1337 if (cc == ')') // format: (a,b,c)
Chris@16 1338 {
Chris@16 1339 q = quaternion<T>(a,b,c);
Chris@16 1340 }
Chris@16 1341 else if (cc == ',') // read "(a,b,c,", possible: (a,b,c,d)
Chris@16 1342 {
Chris@16 1343 is >> d; // we extract the fourth component
Chris@16 1344
Chris@16 1345 if (!is.good()) goto finish;
Chris@16 1346
Chris@16 1347 is >> ch; // get the ninth lexeme
Chris@16 1348
Chris@16 1349 if (!is.good()) goto finish;
Chris@16 1350
Chris@16 1351 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1352 cc = ch;
Chris@16 1353 #else
Chris@16 1354 cc = ct.narrow(ch, char());
Chris@16 1355 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1356
Chris@16 1357 if (cc == ')') // format: (a,b,c,d)
Chris@16 1358 {
Chris@16 1359 q = quaternion<T>(a,b,c,d);
Chris@16 1360 }
Chris@16 1361 else // error
Chris@16 1362 {
Chris@16 1363 is.setstate(::std::ios_base::failbit);
Chris@16 1364 }
Chris@16 1365 }
Chris@16 1366 else // error
Chris@16 1367 {
Chris@16 1368 is.setstate(::std::ios_base::failbit);
Chris@16 1369 }
Chris@16 1370 }
Chris@16 1371 else // error
Chris@16 1372 {
Chris@16 1373 is.setstate(::std::ios_base::failbit);
Chris@16 1374 }
Chris@16 1375 }
Chris@16 1376 }
Chris@16 1377 else // error
Chris@16 1378 {
Chris@16 1379 is.setstate(::std::ios_base::failbit);
Chris@16 1380 }
Chris@16 1381 }
Chris@16 1382 }
Chris@16 1383 else // format: a
Chris@16 1384 {
Chris@16 1385 is.putback(ch);
Chris@16 1386
Chris@16 1387 is >> a; // we extract the first component
Chris@16 1388
Chris@16 1389 if (!is.good()) goto finish;
Chris@16 1390
Chris@16 1391 q = quaternion<T>(a);
Chris@16 1392 }
Chris@16 1393
Chris@16 1394 finish:
Chris@16 1395 return(is);
Chris@16 1396 }
Chris@16 1397
Chris@16 1398
Chris@16 1399 template<typename T, typename charT, class traits>
Chris@16 1400 ::std::basic_ostream<charT,traits> & operator << ( ::std::basic_ostream<charT,traits> & os,
Chris@16 1401 quaternion<T> const & q)
Chris@16 1402 {
Chris@16 1403 ::std::basic_ostringstream<charT,traits> s;
Chris@101 1404
Chris@16 1405 s.flags(os.flags());
Chris@16 1406 #ifdef BOOST_NO_STD_LOCALE
Chris@16 1407 #else
Chris@16 1408 s.imbue(os.getloc());
Chris@16 1409 #endif /* BOOST_NO_STD_LOCALE */
Chris@16 1410 s.precision(os.precision());
Chris@16 1411
Chris@16 1412 s << '(' << q.R_component_1() << ','
Chris@16 1413 << q.R_component_2() << ','
Chris@16 1414 << q.R_component_3() << ','
Chris@16 1415 << q.R_component_4() << ')';
Chris@16 1416
Chris@16 1417 return os << s.str();
Chris@16 1418 }
Chris@16 1419
Chris@16 1420
Chris@16 1421 // values
Chris@16 1422
Chris@16 1423 template<typename T>
Chris@16 1424 inline T real(quaternion<T> const & q)
Chris@16 1425 {
Chris@16 1426 return(q.real());
Chris@16 1427 }
Chris@16 1428
Chris@16 1429
Chris@16 1430 template<typename T>
Chris@16 1431 inline quaternion<T> unreal(quaternion<T> const & q)
Chris@16 1432 {
Chris@16 1433 return(q.unreal());
Chris@16 1434 }
Chris@16 1435
Chris@16 1436
Chris@16 1437 #define BOOST_QUATERNION_VALARRAY_LOADER \
Chris@16 1438 using ::std::valarray; \
Chris@16 1439 \
Chris@16 1440 valarray<T> temp(4); \
Chris@16 1441 \
Chris@16 1442 temp[0] = q.R_component_1(); \
Chris@16 1443 temp[1] = q.R_component_2(); \
Chris@16 1444 temp[2] = q.R_component_3(); \
Chris@16 1445 temp[3] = q.R_component_4();
Chris@16 1446
Chris@16 1447
Chris@16 1448 template<typename T>
Chris@16 1449 inline T sup(quaternion<T> const & q)
Chris@16 1450 {
Chris@16 1451 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
Chris@16 1452 using ::std::abs;
Chris@16 1453 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
Chris@16 1454
Chris@16 1455 BOOST_QUATERNION_VALARRAY_LOADER
Chris@16 1456
Chris@16 1457 return((abs(temp).max)());
Chris@16 1458 }
Chris@16 1459
Chris@16 1460
Chris@16 1461 template<typename T>
Chris@16 1462 inline T l1(quaternion<T> const & q)
Chris@16 1463 {
Chris@16 1464 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
Chris@16 1465 using ::std::abs;
Chris@16 1466 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
Chris@16 1467
Chris@16 1468 BOOST_QUATERNION_VALARRAY_LOADER
Chris@16 1469
Chris@16 1470 return(abs(temp).sum());
Chris@16 1471 }
Chris@16 1472
Chris@16 1473
Chris@16 1474 template<typename T>
Chris@16 1475 inline T abs(quaternion<T> const & q)
Chris@16 1476 {
Chris@16 1477 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
Chris@16 1478 using ::std::abs;
Chris@16 1479 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
Chris@16 1480
Chris@16 1481 using ::std::sqrt;
Chris@16 1482
Chris@16 1483 BOOST_QUATERNION_VALARRAY_LOADER
Chris@16 1484
Chris@16 1485 T maxim = (abs(temp).max)(); // overflow protection
Chris@16 1486
Chris@16 1487 if (maxim == static_cast<T>(0))
Chris@16 1488 {
Chris@16 1489 return(maxim);
Chris@16 1490 }
Chris@16 1491 else
Chris@16 1492 {
Chris@16 1493 T mixam = static_cast<T>(1)/maxim; // prefer multiplications over divisions
Chris@16 1494
Chris@16 1495 temp *= mixam;
Chris@16 1496
Chris@16 1497 temp *= temp;
Chris@16 1498
Chris@16 1499 return(maxim*sqrt(temp.sum()));
Chris@16 1500 }
Chris@16 1501
Chris@16 1502 //return(sqrt(norm(q)));
Chris@16 1503 }
Chris@16 1504
Chris@16 1505
Chris@16 1506 #undef BOOST_QUATERNION_VALARRAY_LOADER
Chris@16 1507
Chris@16 1508
Chris@16 1509 // Note: This is the Cayley norm, not the Euclidian norm...
Chris@16 1510
Chris@16 1511 template<typename T>
Chris@16 1512 inline T norm(quaternion<T>const & q)
Chris@16 1513 {
Chris@16 1514 return(real(q*conj(q)));
Chris@16 1515 }
Chris@16 1516
Chris@16 1517
Chris@16 1518 template<typename T>
Chris@16 1519 inline quaternion<T> conj(quaternion<T> const & q)
Chris@16 1520 {
Chris@16 1521 return(quaternion<T>( +q.R_component_1(),
Chris@16 1522 -q.R_component_2(),
Chris@16 1523 -q.R_component_3(),
Chris@16 1524 -q.R_component_4()));
Chris@16 1525 }
Chris@16 1526
Chris@16 1527
Chris@16 1528 template<typename T>
Chris@16 1529 inline quaternion<T> spherical( T const & rho,
Chris@16 1530 T const & theta,
Chris@16 1531 T const & phi1,
Chris@16 1532 T const & phi2)
Chris@16 1533 {
Chris@16 1534 using ::std::cos;
Chris@16 1535 using ::std::sin;
Chris@16 1536
Chris@16 1537 //T a = cos(theta)*cos(phi1)*cos(phi2);
Chris@16 1538 //T b = sin(theta)*cos(phi1)*cos(phi2);
Chris@16 1539 //T c = sin(phi1)*cos(phi2);
Chris@16 1540 //T d = sin(phi2);
Chris@16 1541
Chris@16 1542 T courrant = static_cast<T>(1);
Chris@16 1543
Chris@16 1544 T d = sin(phi2);
Chris@16 1545
Chris@16 1546 courrant *= cos(phi2);
Chris@16 1547
Chris@16 1548 T c = sin(phi1)*courrant;
Chris@16 1549
Chris@16 1550 courrant *= cos(phi1);
Chris@16 1551
Chris@16 1552 T b = sin(theta)*courrant;
Chris@16 1553 T a = cos(theta)*courrant;
Chris@16 1554
Chris@16 1555 return(rho*quaternion<T>(a,b,c,d));
Chris@16 1556 }
Chris@16 1557
Chris@16 1558
Chris@16 1559 template<typename T>
Chris@16 1560 inline quaternion<T> semipolar( T const & rho,
Chris@16 1561 T const & alpha,
Chris@16 1562 T const & theta1,
Chris@16 1563 T const & theta2)
Chris@16 1564 {
Chris@16 1565 using ::std::cos;
Chris@16 1566 using ::std::sin;
Chris@16 1567
Chris@16 1568 T a = cos(alpha)*cos(theta1);
Chris@16 1569 T b = cos(alpha)*sin(theta1);
Chris@16 1570 T c = sin(alpha)*cos(theta2);
Chris@16 1571 T d = sin(alpha)*sin(theta2);
Chris@16 1572
Chris@16 1573 return(rho*quaternion<T>(a,b,c,d));
Chris@16 1574 }
Chris@16 1575
Chris@16 1576
Chris@16 1577 template<typename T>
Chris@16 1578 inline quaternion<T> multipolar( T const & rho1,
Chris@16 1579 T const & theta1,
Chris@16 1580 T const & rho2,
Chris@16 1581 T const & theta2)
Chris@16 1582 {
Chris@16 1583 using ::std::cos;
Chris@16 1584 using ::std::sin;
Chris@16 1585
Chris@16 1586 T a = rho1*cos(theta1);
Chris@16 1587 T b = rho1*sin(theta1);
Chris@16 1588 T c = rho2*cos(theta2);
Chris@16 1589 T d = rho2*sin(theta2);
Chris@16 1590
Chris@16 1591 return(quaternion<T>(a,b,c,d));
Chris@16 1592 }
Chris@16 1593
Chris@16 1594
Chris@16 1595 template<typename T>
Chris@16 1596 inline quaternion<T> cylindrospherical( T const & t,
Chris@16 1597 T const & radius,
Chris@16 1598 T const & longitude,
Chris@16 1599 T const & latitude)
Chris@16 1600 {
Chris@16 1601 using ::std::cos;
Chris@16 1602 using ::std::sin;
Chris@16 1603
Chris@16 1604
Chris@16 1605
Chris@16 1606 T b = radius*cos(longitude)*cos(latitude);
Chris@16 1607 T c = radius*sin(longitude)*cos(latitude);
Chris@16 1608 T d = radius*sin(latitude);
Chris@16 1609
Chris@16 1610 return(quaternion<T>(t,b,c,d));
Chris@16 1611 }
Chris@16 1612
Chris@16 1613
Chris@16 1614 template<typename T>
Chris@16 1615 inline quaternion<T> cylindrical(T const & r,
Chris@16 1616 T const & angle,
Chris@16 1617 T const & h1,
Chris@16 1618 T const & h2)
Chris@16 1619 {
Chris@16 1620 using ::std::cos;
Chris@16 1621 using ::std::sin;
Chris@16 1622
Chris@16 1623 T a = r*cos(angle);
Chris@16 1624 T b = r*sin(angle);
Chris@16 1625
Chris@16 1626 return(quaternion<T>(a,b,h1,h2));
Chris@16 1627 }
Chris@16 1628
Chris@16 1629
Chris@16 1630 // transcendentals
Chris@16 1631 // (please see the documentation)
Chris@16 1632
Chris@16 1633
Chris@16 1634 template<typename T>
Chris@16 1635 inline quaternion<T> exp(quaternion<T> const & q)
Chris@16 1636 {
Chris@16 1637 using ::std::exp;
Chris@16 1638 using ::std::cos;
Chris@16 1639
Chris@16 1640 using ::boost::math::sinc_pi;
Chris@16 1641
Chris@16 1642 T u = exp(real(q));
Chris@16 1643
Chris@16 1644 T z = abs(unreal(q));
Chris@16 1645
Chris@16 1646 T w = sinc_pi(z);
Chris@16 1647
Chris@16 1648 return(u*quaternion<T>(cos(z),
Chris@16 1649 w*q.R_component_2(), w*q.R_component_3(),
Chris@16 1650 w*q.R_component_4()));
Chris@16 1651 }
Chris@16 1652
Chris@16 1653
Chris@16 1654 template<typename T>
Chris@16 1655 inline quaternion<T> cos(quaternion<T> const & q)
Chris@16 1656 {
Chris@16 1657 using ::std::sin;
Chris@16 1658 using ::std::cos;
Chris@16 1659 using ::std::cosh;
Chris@16 1660
Chris@16 1661 using ::boost::math::sinhc_pi;
Chris@16 1662
Chris@16 1663 T z = abs(unreal(q));
Chris@16 1664
Chris@16 1665 T w = -sin(q.real())*sinhc_pi(z);
Chris@16 1666
Chris@16 1667 return(quaternion<T>(cos(q.real())*cosh(z),
Chris@16 1668 w*q.R_component_2(), w*q.R_component_3(),
Chris@16 1669 w*q.R_component_4()));
Chris@16 1670 }
Chris@16 1671
Chris@16 1672
Chris@16 1673 template<typename T>
Chris@16 1674 inline quaternion<T> sin(quaternion<T> const & q)
Chris@16 1675 {
Chris@16 1676 using ::std::sin;
Chris@16 1677 using ::std::cos;
Chris@16 1678 using ::std::cosh;
Chris@16 1679
Chris@16 1680 using ::boost::math::sinhc_pi;
Chris@16 1681
Chris@16 1682 T z = abs(unreal(q));
Chris@16 1683
Chris@16 1684 T w = +cos(q.real())*sinhc_pi(z);
Chris@16 1685
Chris@16 1686 return(quaternion<T>(sin(q.real())*cosh(z),
Chris@16 1687 w*q.R_component_2(), w*q.R_component_3(),
Chris@16 1688 w*q.R_component_4()));
Chris@16 1689 }
Chris@16 1690
Chris@16 1691
Chris@16 1692 template<typename T>
Chris@16 1693 inline quaternion<T> tan(quaternion<T> const & q)
Chris@16 1694 {
Chris@16 1695 return(sin(q)/cos(q));
Chris@16 1696 }
Chris@16 1697
Chris@16 1698
Chris@16 1699 template<typename T>
Chris@16 1700 inline quaternion<T> cosh(quaternion<T> const & q)
Chris@16 1701 {
Chris@16 1702 return((exp(+q)+exp(-q))/static_cast<T>(2));
Chris@16 1703 }
Chris@16 1704
Chris@16 1705
Chris@16 1706 template<typename T>
Chris@16 1707 inline quaternion<T> sinh(quaternion<T> const & q)
Chris@16 1708 {
Chris@16 1709 return((exp(+q)-exp(-q))/static_cast<T>(2));
Chris@16 1710 }
Chris@16 1711
Chris@16 1712
Chris@16 1713 template<typename T>
Chris@16 1714 inline quaternion<T> tanh(quaternion<T> const & q)
Chris@16 1715 {
Chris@16 1716 return(sinh(q)/cosh(q));
Chris@16 1717 }
Chris@16 1718
Chris@16 1719
Chris@16 1720 template<typename T>
Chris@16 1721 quaternion<T> pow(quaternion<T> const & q,
Chris@16 1722 int n)
Chris@16 1723 {
Chris@16 1724 if (n > 1)
Chris@16 1725 {
Chris@16 1726 int m = n>>1;
Chris@16 1727
Chris@16 1728 quaternion<T> result = pow(q, m);
Chris@16 1729
Chris@16 1730 result *= result;
Chris@16 1731
Chris@16 1732 if (n != (m<<1))
Chris@16 1733 {
Chris@16 1734 result *= q; // n odd
Chris@16 1735 }
Chris@16 1736
Chris@16 1737 return(result);
Chris@16 1738 }
Chris@16 1739 else if (n == 1)
Chris@16 1740 {
Chris@16 1741 return(q);
Chris@16 1742 }
Chris@16 1743 else if (n == 0)
Chris@16 1744 {
Chris@16 1745 return(quaternion<T>(static_cast<T>(1)));
Chris@16 1746 }
Chris@16 1747 else /* n < 0 */
Chris@16 1748 {
Chris@16 1749 return(pow(quaternion<T>(static_cast<T>(1))/q,-n));
Chris@16 1750 }
Chris@16 1751 }
Chris@16 1752
Chris@16 1753
Chris@16 1754 // helper templates for converting copy constructors (definition)
Chris@16 1755
Chris@16 1756 namespace detail
Chris@16 1757 {
Chris@16 1758
Chris@16 1759 template< typename T,
Chris@16 1760 typename U
Chris@16 1761 >
Chris@16 1762 quaternion<T> quaternion_type_converter(quaternion<U> const & rhs)
Chris@16 1763 {
Chris@16 1764 return(quaternion<T>( static_cast<T>(rhs.R_component_1()),
Chris@16 1765 static_cast<T>(rhs.R_component_2()),
Chris@16 1766 static_cast<T>(rhs.R_component_3()),
Chris@16 1767 static_cast<T>(rhs.R_component_4())));
Chris@16 1768 }
Chris@16 1769 }
Chris@16 1770 }
Chris@16 1771 }
Chris@16 1772
Chris@16 1773 #endif /* BOOST_QUATERNION_HPP */