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