1 // boost octonion.hpp header file
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)
8 // See http://www.boost.org for updates, documentation, and revision history.
11 #ifndef BOOST_OCTONION_HPP
12 #define BOOST_OCTONION_HPP
14 #include <boost/math/quaternion.hpp>
21 #if BOOST_WORKAROUND(__GNUC__, < 3)
22 // gcc 2.95.x uses expression templates for valarray calculations, but
23 // the result is not conforming. We need BOOST_GET_VALARRAY to get an
24 // actual valarray result when we need to call a member function
25 #define BOOST_GET_VALARRAY(T,x) ::std::valarray<T>(x)
26 // gcc 2.95.x has an "std::ios" class that is similar to
27 // "std::ios_base", so we just use a #define
28 #define BOOST_IOS_BASE ::std::ios
29 // gcc 2.x ignores function scope using declarations,
30 // put them in the scope of the enclosing namespace instead:
31 using ::std::valarray
;
37 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
39 #define BOOST_OCTONION_ACCESSOR_GENERATOR(type) \
45 octonion<type> unreal() const \
47 return( octonion<type>(static_cast<type>(0),b,c,d,e,f,g,h)); \
50 type R_component_1() const \
55 type R_component_2() const \
60 type R_component_3() const \
65 type R_component_4() const \
70 type R_component_5() const \
75 type R_component_6() const \
80 type R_component_7() const \
85 type R_component_8() const \
90 ::std::complex<type> C_component_1() const \
92 return(::std::complex<type>(a,b)); \
95 ::std::complex<type> C_component_2() const \
97 return(::std::complex<type>(c,d)); \
100 ::std::complex<type> C_component_3() const \
102 return(::std::complex<type>(e,f)); \
105 ::std::complex<type> C_component_4() const \
107 return(::std::complex<type>(g,h)); \
110 ::boost::math::quaternion<type> H_component_1() const \
112 return(::boost::math::quaternion<type>(a,b,c,d)); \
115 ::boost::math::quaternion<type> H_component_2() const \
117 return(::boost::math::quaternion<type>(e,f,g,h)); \
121 #define BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type) \
122 template<typename X> \
123 octonion<type> & operator = (octonion<X> const & a_affecter) \
125 a = static_cast<type>(a_affecter.R_component_1()); \
126 b = static_cast<type>(a_affecter.R_component_2()); \
127 c = static_cast<type>(a_affecter.R_component_3()); \
128 d = static_cast<type>(a_affecter.R_component_4()); \
129 e = static_cast<type>(a_affecter.R_component_5()); \
130 f = static_cast<type>(a_affecter.R_component_6()); \
131 g = static_cast<type>(a_affecter.R_component_7()); \
132 h = static_cast<type>(a_affecter.R_component_8()); \
137 octonion<type> & operator = (octonion<type> const & a_affecter) \
151 octonion<type> & operator = (type const & a_affecter) \
155 b = c = d = e = f= g = h = static_cast<type>(0); \
160 octonion<type> & operator = (::std::complex<type> const & a_affecter) \
162 a = a_affecter.real(); \
163 b = a_affecter.imag(); \
165 c = d = e = f = g = h = static_cast<type>(0); \
170 octonion<type> & operator = (::boost::math::quaternion<type> const & a_affecter) \
172 a = a_affecter.R_component_1(); \
173 b = a_affecter.R_component_2(); \
174 c = a_affecter.R_component_3(); \
175 d = a_affecter.R_component_4(); \
177 e = f = g = h = static_cast<type>(0); \
183 #define BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \
199 typedef T value_type
;
201 // constructor for O seen as R^8
202 // (also default constructor)
204 explicit octonion( T
const & requested_a
= T(),
205 T
const & requested_b
= T(),
206 T
const & requested_c
= T(),
207 T
const & requested_d
= T(),
208 T
const & requested_e
= T(),
209 T
const & requested_f
= T(),
210 T
const & requested_g
= T(),
211 T
const & requested_h
= T())
225 // constructor for H seen as C^4
227 explicit octonion( ::std::complex<T
> const & z0
,
228 ::std::complex<T
> const & z1
= ::std::complex<T
>(),
229 ::std::complex<T
> const & z2
= ::std::complex<T
>(),
230 ::std::complex<T
> const & z3
= ::std::complex<T
>())
244 // constructor for O seen as H^2
246 explicit octonion( ::boost::math::quaternion
<T
> const & q0
,
247 ::boost::math::quaternion
<T
> const & q1
= ::boost::math::quaternion
<T
>())
248 : a(q0
.R_component_1()),
249 b(q0
.R_component_2()),
250 c(q0
.R_component_3()),
251 d(q0
.R_component_4()),
252 e(q1
.R_component_1()),
253 f(q1
.R_component_2()),
254 g(q1
.R_component_3()),
255 h(q1
.R_component_4())
261 // UNtemplated copy constructor
262 // (this is taken care of by the compiler itself)
265 // templated copy constructor
268 explicit octonion(octonion
<X
> const & a_recopier
)
269 : a(static_cast<T
>(a_recopier
.R_component_1())),
270 b(static_cast<T
>(a_recopier
.R_component_2())),
271 c(static_cast<T
>(a_recopier
.R_component_3())),
272 d(static_cast<T
>(a_recopier
.R_component_4())),
273 e(static_cast<T
>(a_recopier
.R_component_5())),
274 f(static_cast<T
>(a_recopier
.R_component_6())),
275 g(static_cast<T
>(a_recopier
.R_component_7())),
276 h(static_cast<T
>(a_recopier
.R_component_8()))
283 // (this is taken care of by the compiler itself)
288 // Note: Like complex number, octonions do have a meaningful notion of "real part",
289 // but unlike them there is no meaningful notion of "imaginary part".
290 // Instead there is an "unreal part" which itself is an octonion, and usually
291 // nothing simpler (as opposed to the complex number case).
292 // However, for practicallity, there are accessors for the other components
293 // (these are necessary for the templated copy constructor, for instance).
295 BOOST_OCTONION_ACCESSOR_GENERATOR(T
)
297 // assignment operators
299 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T
)
301 // other assignment-related operators
303 // NOTE: Octonion multiplication is *NOT* commutative;
304 // symbolically, "q *= rhs;" means "q = q * rhs;"
305 // and "q /= rhs;" means "q = q * inverse_of(rhs);";
306 // octonion multiplication is also *NOT* associative
308 octonion
<T
> & operator += (T
const & rhs
)
310 T at
= a
+ rhs
; // exception guard
318 octonion
<T
> & operator += (::std::complex<T
> const & rhs
)
320 T at
= a
+ rhs
.real(); // exception guard
321 T bt
= b
+ rhs
.imag(); // exception guard
330 octonion
<T
> & operator += (::boost::math::quaternion
<T
> const & rhs
)
332 T at
= a
+ rhs
.R_component_1(); // exception guard
333 T bt
= b
+ rhs
.R_component_2(); // exception guard
334 T ct
= c
+ rhs
.R_component_3(); // exception guard
335 T dt
= d
+ rhs
.R_component_4(); // exception guard
347 octonion
<T
> & operator += (octonion
<X
> const & rhs
)
349 T at
= a
+ static_cast<T
>(rhs
.R_component_1()); // exception guard
350 T bt
= b
+ static_cast<T
>(rhs
.R_component_2()); // exception guard
351 T ct
= c
+ static_cast<T
>(rhs
.R_component_3()); // exception guard
352 T dt
= d
+ static_cast<T
>(rhs
.R_component_4()); // exception guard
353 T et
= e
+ static_cast<T
>(rhs
.R_component_5()); // exception guard
354 T ft
= f
+ static_cast<T
>(rhs
.R_component_6()); // exception guard
355 T gt
= g
+ static_cast<T
>(rhs
.R_component_7()); // exception guard
356 T ht
= h
+ static_cast<T
>(rhs
.R_component_8()); // exception guard
372 octonion
<T
> & operator -= (T
const & rhs
)
374 T at
= a
- rhs
; // exception guard
382 octonion
<T
> & operator -= (::std::complex<T
> const & rhs
)
384 T at
= a
- rhs
.real(); // exception guard
385 T bt
= b
- rhs
.imag(); // exception guard
394 octonion
<T
> & operator -= (::boost::math::quaternion
<T
> const & rhs
)
396 T at
= a
- rhs
.R_component_1(); // exception guard
397 T bt
= b
- rhs
.R_component_2(); // exception guard
398 T ct
= c
- rhs
.R_component_3(); // exception guard
399 T dt
= d
- rhs
.R_component_4(); // exception guard
411 octonion
<T
> & operator -= (octonion
<X
> const & rhs
)
413 T at
= a
- static_cast<T
>(rhs
.R_component_1()); // exception guard
414 T bt
= b
- static_cast<T
>(rhs
.R_component_2()); // exception guard
415 T ct
= c
- static_cast<T
>(rhs
.R_component_3()); // exception guard
416 T dt
= d
- static_cast<T
>(rhs
.R_component_4()); // exception guard
417 T et
= e
- static_cast<T
>(rhs
.R_component_5()); // exception guard
418 T ft
= f
- static_cast<T
>(rhs
.R_component_6()); // exception guard
419 T gt
= g
- static_cast<T
>(rhs
.R_component_7()); // exception guard
420 T ht
= h
- static_cast<T
>(rhs
.R_component_8()); // exception guard
435 octonion
<T
> & operator *= (T
const & rhs
)
437 T at
= a
* rhs
; // exception guard
438 T bt
= b
* rhs
; // exception guard
439 T ct
= c
* rhs
; // exception guard
440 T dt
= d
* rhs
; // exception guard
441 T et
= e
* rhs
; // exception guard
442 T ft
= f
* rhs
; // exception guard
443 T gt
= g
* rhs
; // exception guard
444 T ht
= h
* rhs
; // exception guard
459 octonion
<T
> & operator *= (::std::complex<T
> const & rhs
)
486 octonion
<T
> & operator *= (::boost::math::quaternion
<T
> const & rhs
)
488 T ar
= rhs
.R_component_1();
489 T br
= rhs
.R_component_2();
490 T cr
= rhs
.R_component_2();
491 T dr
= rhs
.R_component_2();
493 T at
= +a
*ar
-b
*br
-c
*cr
-d
*dr
;
494 T bt
= +a
*br
+b
*ar
+c
*dr
-d
*cr
;
495 T ct
= +a
*cr
-b
*dr
+c
*ar
+d
*br
;
496 T dt
= +a
*dr
+b
*cr
-c
*br
+d
*ar
;
497 T et
= +e
*ar
+f
*br
+g
*cr
+h
*dr
;
498 T ft
= -e
*br
+f
*ar
-g
*dr
+h
*cr
;
499 T gt
= -e
*cr
+f
*dr
+g
*ar
-h
*br
;
500 T ht
= -e
*dr
-f
*cr
+g
*br
+h
*ar
;
516 octonion
<T
> & operator *= (octonion
<X
> const & rhs
)
518 T ar
= static_cast<T
>(rhs
.R_component_1());
519 T br
= static_cast<T
>(rhs
.R_component_2());
520 T cr
= static_cast<T
>(rhs
.R_component_3());
521 T dr
= static_cast<T
>(rhs
.R_component_4());
522 T er
= static_cast<T
>(rhs
.R_component_5());
523 T fr
= static_cast<T
>(rhs
.R_component_6());
524 T gr
= static_cast<T
>(rhs
.R_component_7());
525 T hr
= static_cast<T
>(rhs
.R_component_8());
527 T at
= +a
*ar
-b
*br
-c
*cr
-d
*dr
-e
*er
-f
*fr
-g
*gr
-h
*hr
;
528 T bt
= +a
*br
+b
*ar
+c
*dr
-d
*cr
+e
*fr
-f
*er
-g
*hr
+h
*gr
;
529 T ct
= +a
*cr
-b
*dr
+c
*ar
+d
*br
+e
*gr
+f
*hr
-g
*er
-h
*fr
;
530 T dt
= +a
*dr
+b
*cr
-c
*br
+d
*ar
+e
*hr
-f
*gr
+g
*fr
-h
*er
;
531 T et
= +a
*er
-b
*fr
-c
*gr
-d
*hr
+e
*ar
+f
*br
+g
*cr
+h
*dr
;
532 T ft
= +a
*fr
+b
*er
-c
*hr
+d
*gr
-e
*br
+f
*ar
-g
*dr
+h
*cr
;
533 T gt
= +a
*gr
+b
*hr
+c
*er
-d
*fr
-e
*cr
+f
*dr
+g
*ar
-h
*br
;
534 T ht
= +a
*hr
-b
*gr
+c
*fr
+d
*er
-e
*dr
-f
*cr
+g
*br
+h
*ar
;
549 octonion
<T
> & operator /= (T
const & rhs
)
551 T at
= a
/ rhs
; // exception guard
552 T bt
= b
/ rhs
; // exception guard
553 T ct
= c
/ rhs
; // exception guard
554 T dt
= d
/ rhs
; // exception guard
555 T et
= e
/ rhs
; // exception guard
556 T ft
= f
/ rhs
; // exception guard
557 T gt
= g
/ rhs
; // exception guard
558 T ht
= h
/ rhs
; // exception guard
573 octonion
<T
> & operator /= (::std::complex<T
> const & rhs
)
578 T denominator
= ar
*ar
+br
*br
;
580 T at
= (+a
*ar
-b
*br
)/denominator
;
581 T bt
= (-a
*br
+b
*ar
)/denominator
;
582 T ct
= (+c
*ar
-d
*br
)/denominator
;
583 T dt
= (+c
*br
+d
*ar
)/denominator
;
584 T et
= (+e
*ar
-f
*br
)/denominator
;
585 T ft
= (+e
*br
+f
*ar
)/denominator
;
586 T gt
= (+g
*ar
+h
*br
)/denominator
;
587 T ht
= (+g
*br
+h
*ar
)/denominator
;
602 octonion
<T
> & operator /= (::boost::math::quaternion
<T
> const & rhs
)
604 T ar
= rhs
.R_component_1();
605 T br
= rhs
.R_component_2();
606 T cr
= rhs
.R_component_2();
607 T dr
= rhs
.R_component_2();
609 T denominator
= ar
*ar
+br
*br
+cr
*cr
+dr
*dr
;
611 T at
= (+a
*ar
+b
*br
+c
*cr
+d
*dr
)/denominator
;
612 T bt
= (-a
*br
+b
*ar
-c
*dr
+d
*cr
)/denominator
;
613 T ct
= (-a
*cr
+b
*dr
+c
*ar
-d
*br
)/denominator
;
614 T dt
= (-a
*dr
-b
*cr
+c
*br
+d
*ar
)/denominator
;
615 T et
= (+e
*ar
-f
*br
-g
*cr
-h
*dr
)/denominator
;
616 T ft
= (+e
*br
+f
*ar
+g
*dr
-h
*cr
)/denominator
;
617 T gt
= (+e
*cr
-f
*dr
+g
*ar
+h
*br
)/denominator
;
618 T ht
= (+e
*dr
+f
*cr
-g
*br
+h
*ar
)/denominator
;
634 octonion
<T
> & operator /= (octonion
<X
> const & rhs
)
636 T ar
= static_cast<T
>(rhs
.R_component_1());
637 T br
= static_cast<T
>(rhs
.R_component_2());
638 T cr
= static_cast<T
>(rhs
.R_component_3());
639 T dr
= static_cast<T
>(rhs
.R_component_4());
640 T er
= static_cast<T
>(rhs
.R_component_5());
641 T fr
= static_cast<T
>(rhs
.R_component_6());
642 T gr
= static_cast<T
>(rhs
.R_component_7());
643 T hr
= static_cast<T
>(rhs
.R_component_8());
645 T denominator
= ar
*ar
+br
*br
+cr
*cr
+dr
*dr
+er
*er
+fr
*fr
+gr
*gr
+hr
*hr
;
647 T at
= (+a
*ar
+b
*br
+c
*cr
+d
*dr
+e
*er
+f
*fr
+g
*gr
+h
*hr
)/denominator
;
648 T bt
= (-a
*br
+b
*ar
-c
*dr
+d
*cr
-e
*fr
+f
*er
+g
*hr
-h
*gr
)/denominator
;
649 T ct
= (-a
*cr
+b
*dr
+c
*ar
-d
*br
-e
*gr
-f
*hr
+g
*er
+h
*fr
)/denominator
;
650 T dt
= (-a
*dr
-b
*cr
+c
*br
+d
*ar
-e
*hr
+f
*gr
-g
*fr
+h
*er
)/denominator
;
651 T et
= (-a
*er
+b
*fr
+c
*gr
+d
*hr
+e
*ar
-f
*br
-g
*cr
-h
*dr
)/denominator
;
652 T ft
= (-a
*fr
-b
*er
+c
*hr
-d
*gr
+e
*br
+f
*ar
+g
*dr
-h
*cr
)/denominator
;
653 T gt
= (-a
*gr
-b
*hr
-c
*er
+d
*fr
+e
*cr
-f
*dr
+g
*ar
+h
*br
)/denominator
;
654 T ht
= (-a
*hr
+b
*gr
-c
*fr
-d
*er
+e
*dr
+f
*cr
-g
*br
+h
*ar
)/denominator
;
671 BOOST_OCTONION_MEMBER_DATA_GENERATOR(T
)
679 // declaration of octonion specialization
681 template<> class octonion
<float>;
682 template<> class octonion
<double>;
683 template<> class octonion
<long double>;
686 // helper templates for converting copy constructors (declaration)
691 template< typename T
,
694 octonion
<T
> octonion_type_converter(octonion
<U
> const & rhs
);
698 // implementation of octonion specialization
701 #define BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type) \
702 explicit octonion( type const & requested_a = static_cast<type>(0), \
703 type const & requested_b = static_cast<type>(0), \
704 type const & requested_c = static_cast<type>(0), \
705 type const & requested_d = static_cast<type>(0), \
706 type const & requested_e = static_cast<type>(0), \
707 type const & requested_f = static_cast<type>(0), \
708 type const & requested_g = static_cast<type>(0), \
709 type const & requested_h = static_cast<type>(0)) \
721 explicit octonion( ::std::complex<type> const & z0, \
722 ::std::complex<type> const & z1 = ::std::complex<type>(), \
723 ::std::complex<type> const & z2 = ::std::complex<type>(), \
724 ::std::complex<type> const & z3 = ::std::complex<type>()) \
736 explicit octonion( ::boost::math::quaternion<type> const & q0, \
737 ::boost::math::quaternion<type> const & q1 = ::boost::math::quaternion<type>()) \
738 : a(q0.R_component_1()), \
739 b(q0.R_component_2()), \
740 c(q0.R_component_3()), \
741 d(q0.R_component_4()), \
742 e(q1.R_component_1()), \
743 f(q1.R_component_2()), \
744 g(q1.R_component_3()), \
745 h(q1.R_component_4()) \
750 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \
751 octonion<type> & operator += (type const & rhs) \
758 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \
759 octonion<type> & operator += (::std::complex<type> const & rhs) \
767 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \
768 octonion<type> & operator += (::boost::math::quaternion<type> const & rhs) \
770 a += rhs.R_component_1(); \
771 b += rhs.R_component_2(); \
772 c += rhs.R_component_3(); \
773 d += rhs.R_component_4(); \
778 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) \
779 template<typename X> \
780 octonion<type> & operator += (octonion<X> const & rhs) \
782 a += static_cast<type>(rhs.R_component_1()); \
783 b += static_cast<type>(rhs.R_component_2()); \
784 c += static_cast<type>(rhs.R_component_3()); \
785 d += static_cast<type>(rhs.R_component_4()); \
786 e += static_cast<type>(rhs.R_component_5()); \
787 f += static_cast<type>(rhs.R_component_6()); \
788 g += static_cast<type>(rhs.R_component_7()); \
789 h += static_cast<type>(rhs.R_component_8()); \
794 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \
795 octonion<type> & operator -= (type const & rhs) \
802 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \
803 octonion<type> & operator -= (::std::complex<type> const & rhs) \
811 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \
812 octonion<type> & operator -= (::boost::math::quaternion<type> const & rhs) \
814 a -= rhs.R_component_1(); \
815 b -= rhs.R_component_2(); \
816 c -= rhs.R_component_3(); \
817 d -= rhs.R_component_4(); \
822 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) \
823 template<typename X> \
824 octonion<type> & operator -= (octonion<X> const & rhs) \
826 a -= static_cast<type>(rhs.R_component_1()); \
827 b -= static_cast<type>(rhs.R_component_2()); \
828 c -= static_cast<type>(rhs.R_component_3()); \
829 d -= static_cast<type>(rhs.R_component_4()); \
830 e -= static_cast<type>(rhs.R_component_5()); \
831 f -= static_cast<type>(rhs.R_component_6()); \
832 g -= static_cast<type>(rhs.R_component_7()); \
833 h -= static_cast<type>(rhs.R_component_8()); \
838 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \
839 octonion<type> & operator *= (type const & rhs) \
853 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \
854 octonion<type> & operator *= (::std::complex<type> const & rhs) \
856 type ar = rhs.real(); \
857 type br = rhs.imag(); \
859 type at = +a*ar-b*br; \
860 type bt = +a*br+b*ar; \
861 type ct = +c*ar+d*br; \
862 type dt = -c*br+d*ar; \
863 type et = +e*ar+f*br; \
864 type ft = -e*br+f*ar; \
865 type gt = +g*ar-h*br; \
866 type ht = +g*br+h*ar; \
880 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \
881 octonion<type> & operator *= (::boost::math::quaternion<type> const & rhs) \
883 type ar = rhs.R_component_1(); \
884 type br = rhs.R_component_2(); \
885 type cr = rhs.R_component_2(); \
886 type dr = rhs.R_component_2(); \
888 type at = +a*ar-b*br-c*cr-d*dr; \
889 type bt = +a*br+b*ar+c*dr-d*cr; \
890 type ct = +a*cr-b*dr+c*ar+d*br; \
891 type dt = +a*dr+b*cr-c*br+d*ar; \
892 type et = +e*ar+f*br+g*cr+h*dr; \
893 type ft = -e*br+f*ar-g*dr+h*cr; \
894 type gt = -e*cr+f*dr+g*ar-h*br; \
895 type ht = -e*dr-f*cr+g*br+h*ar; \
909 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) \
910 template<typename X> \
911 octonion<type> & operator *= (octonion<X> const & rhs) \
913 type ar = static_cast<type>(rhs.R_component_1()); \
914 type br = static_cast<type>(rhs.R_component_2()); \
915 type cr = static_cast<type>(rhs.R_component_3()); \
916 type dr = static_cast<type>(rhs.R_component_4()); \
917 type er = static_cast<type>(rhs.R_component_5()); \
918 type fr = static_cast<type>(rhs.R_component_6()); \
919 type gr = static_cast<type>(rhs.R_component_7()); \
920 type hr = static_cast<type>(rhs.R_component_8()); \
922 type at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; \
923 type bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; \
924 type ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; \
925 type dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; \
926 type et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; \
927 type ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; \
928 type gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; \
929 type ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; \
943 // There is quite a lot of repetition in the code below. This is intentional.
944 // The last conditional block is the normal form, and the others merely
945 // consist of workarounds for various compiler deficiencies. Hopefuly, when
946 // more compilers are conformant and we can retire support for those that are
947 // not, we will be able to remove the clutter. This is makes the situation
948 // (painfully) explicit.
950 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \
951 octonion<type> & operator /= (type const & rhs) \
961 #if defined(__GNUC__) && (__GNUC__ < 3)
962 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \
963 octonion<type> & operator /= (::std::complex<type> const & rhs) \
965 using ::std::valarray; \
967 valarray<type> tr(2); \
969 tr[0] = rhs.real(); \
970 tr[1] = rhs.imag(); \
972 type mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)(); \
976 valarray<type> tt(8); \
978 tt[0] = +a*tr[0]-b*tr[1]; \
979 tt[1] = -a*tr[1]+b*tr[0]; \
980 tt[2] = +c*tr[0]-d*tr[1]; \
981 tt[3] = +c*tr[1]+d*tr[0]; \
982 tt[4] = +e*tr[0]-f*tr[1]; \
983 tt[5] = +e*tr[1]+f*tr[0]; \
984 tt[6] = +g*tr[0]+h*tr[1]; \
985 tt[7] = +g*tr[1]+h*tr[0]; \
989 tt *= (mixam/tr.sum()); \
1002 #elif defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1003 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \
1004 octonion<type> & operator /= (::std::complex<type> const & rhs) \
1006 using ::std::valarray; \
1009 valarray<type> tr(2); \
1011 tr[0] = rhs.real(); \
1012 tr[1] = rhs.imag(); \
1014 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
1018 valarray<type> tt(8); \
1020 tt[0] = +a*tr[0]-b*tr[1]; \
1021 tt[1] = -a*tr[1]+b*tr[0]; \
1022 tt[2] = +c*tr[0]-d*tr[1]; \
1023 tt[3] = +c*tr[1]+d*tr[0]; \
1024 tt[4] = +e*tr[0]-f*tr[1]; \
1025 tt[5] = +e*tr[1]+f*tr[0]; \
1026 tt[6] = +g*tr[0]+h*tr[1]; \
1027 tt[7] = +g*tr[1]+h*tr[0]; \
1031 tt *= (mixam/tr.sum()); \
1045 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \
1046 octonion<type> & operator /= (::std::complex<type> const & rhs) \
1048 using ::std::valarray; \
1050 valarray<type> tr(2); \
1052 tr[0] = rhs.real(); \
1053 tr[1] = rhs.imag(); \
1055 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
1059 valarray<type> tt(8); \
1061 tt[0] = +a*tr[0]-b*tr[1]; \
1062 tt[1] = -a*tr[1]+b*tr[0]; \
1063 tt[2] = +c*tr[0]-d*tr[1]; \
1064 tt[3] = +c*tr[1]+d*tr[0]; \
1065 tt[4] = +e*tr[0]-f*tr[1]; \
1066 tt[5] = +e*tr[1]+f*tr[0]; \
1067 tt[6] = +g*tr[0]+h*tr[1]; \
1068 tt[7] = +g*tr[1]+h*tr[0]; \
1072 tt *= (mixam/tr.sum()); \
1085 #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
1087 #if defined(__GNUC__) && (__GNUC__ < 3)
1088 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \
1089 octonion<type> & operator /= (::boost::math::quaternion<type> const & rhs) \
1091 using ::std::valarray; \
1093 valarray<type> tr(4); \
1095 tr[0] = static_cast<type>(rhs.R_component_1()); \
1096 tr[1] = static_cast<type>(rhs.R_component_2()); \
1097 tr[2] = static_cast<type>(rhs.R_component_3()); \
1098 tr[3] = static_cast<type>(rhs.R_component_4()); \
1100 type mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();\
1104 valarray<type> tt(8); \
1106 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \
1107 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \
1108 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \
1109 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \
1110 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \
1111 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \
1112 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \
1113 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \
1117 tt *= (mixam/tr.sum()); \
1130 #elif defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1131 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \
1132 octonion<type> & operator /= (::boost::math::quaternion<type> const & rhs) \
1134 using ::std::valarray; \
1137 valarray<type> tr(4); \
1139 tr[0] = static_cast<type>(rhs.R_component_1()); \
1140 tr[1] = static_cast<type>(rhs.R_component_2()); \
1141 tr[2] = static_cast<type>(rhs.R_component_3()); \
1142 tr[3] = static_cast<type>(rhs.R_component_4()); \
1144 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
1148 valarray<type> tt(8); \
1150 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \
1151 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \
1152 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \
1153 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \
1154 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \
1155 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \
1156 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \
1157 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \
1161 tt *= (mixam/tr.sum()); \
1175 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \
1176 octonion<type> & operator /= (::boost::math::quaternion<type> const & rhs) \
1178 using ::std::valarray; \
1180 valarray<type> tr(4); \
1182 tr[0] = static_cast<type>(rhs.R_component_1()); \
1183 tr[1] = static_cast<type>(rhs.R_component_2()); \
1184 tr[2] = static_cast<type>(rhs.R_component_3()); \
1185 tr[3] = static_cast<type>(rhs.R_component_4()); \
1187 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
1191 valarray<type> tt(8); \
1193 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \
1194 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \
1195 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \
1196 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \
1197 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \
1198 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \
1199 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \
1200 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \
1204 tt *= (mixam/tr.sum()); \
1217 #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
1219 #if defined(__GNUC__) && (__GNUC__ < 3)
1220 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \
1221 template<typename X> \
1222 octonion<type> & operator /= (octonion<X> const & rhs) \
1224 using ::std::valarray; \
1226 valarray<type> tr(8); \
1228 tr[0] = static_cast<type>(rhs.R_component_1()); \
1229 tr[1] = static_cast<type>(rhs.R_component_2()); \
1230 tr[2] = static_cast<type>(rhs.R_component_3()); \
1231 tr[3] = static_cast<type>(rhs.R_component_4()); \
1232 tr[4] = static_cast<type>(rhs.R_component_5()); \
1233 tr[5] = static_cast<type>(rhs.R_component_6()); \
1234 tr[6] = static_cast<type>(rhs.R_component_7()); \
1235 tr[7] = static_cast<type>(rhs.R_component_8()); \
1237 type mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();\
1241 valarray<type> tt(8); \
1243 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \
1244 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \
1245 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \
1246 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \
1247 tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \
1248 tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \
1249 tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \
1250 tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \
1254 tt *= (mixam/tr.sum()); \
1267 #elif defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1268 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \
1269 template<typename X> \
1270 octonion<type> & operator /= (octonion<X> const & rhs) \
1272 using ::std::valarray; \
1275 valarray<type> tr(8); \
1277 tr[0] = static_cast<type>(rhs.R_component_1()); \
1278 tr[1] = static_cast<type>(rhs.R_component_2()); \
1279 tr[2] = static_cast<type>(rhs.R_component_3()); \
1280 tr[3] = static_cast<type>(rhs.R_component_4()); \
1281 tr[4] = static_cast<type>(rhs.R_component_5()); \
1282 tr[5] = static_cast<type>(rhs.R_component_6()); \
1283 tr[6] = static_cast<type>(rhs.R_component_7()); \
1284 tr[7] = static_cast<type>(rhs.R_component_8()); \
1286 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
1290 valarray<type> tt(8); \
1292 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \
1293 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \
1294 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \
1295 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \
1296 tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \
1297 tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \
1298 tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \
1299 tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \
1303 tt *= (mixam/tr.sum()); \
1317 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \
1318 template<typename X> \
1319 octonion<type> & operator /= (octonion<X> const & rhs) \
1321 using ::std::valarray; \
1323 valarray<type> tr(8); \
1325 tr[0] = static_cast<type>(rhs.R_component_1()); \
1326 tr[1] = static_cast<type>(rhs.R_component_2()); \
1327 tr[2] = static_cast<type>(rhs.R_component_3()); \
1328 tr[3] = static_cast<type>(rhs.R_component_4()); \
1329 tr[4] = static_cast<type>(rhs.R_component_5()); \
1330 tr[5] = static_cast<type>(rhs.R_component_6()); \
1331 tr[6] = static_cast<type>(rhs.R_component_7()); \
1332 tr[7] = static_cast<type>(rhs.R_component_8()); \
1334 type mixam = static_cast<type>(1)/(abs(tr).max)(); \
1338 valarray<type> tt(8); \
1340 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \
1341 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \
1342 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \
1343 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \
1344 tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \
1345 tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \
1346 tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \
1347 tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \
1351 tt *= (mixam/tr.sum()); \
1364 #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
1367 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \
1368 BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \
1369 BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \
1370 BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \
1371 BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)
1373 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \
1374 BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \
1375 BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \
1376 BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \
1377 BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)
1379 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \
1380 BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \
1381 BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \
1382 BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \
1383 BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)
1385 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) \
1386 BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \
1387 BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \
1388 BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \
1389 BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)
1391 #define BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \
1392 BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \
1393 BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \
1394 BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \
1395 BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)
1399 class octonion
<float>
1403 typedef float value_type
;
1405 BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float)
1407 // UNtemplated copy constructor
1408 // (this is taken care of by the compiler itself)
1410 // explicit copy constructors (precision-loosing converters)
1412 explicit octonion(octonion
<double> const & a_recopier
)
1414 *this = detail::octonion_type_converter
<float, double>(a_recopier
);
1417 explicit octonion(octonion
<long double> const & a_recopier
)
1419 *this = detail::octonion_type_converter
<float, long double>(a_recopier
);
1423 // (this is taken care of by the compiler itself)
1427 // Note: Like complex number, octonions do have a meaningful notion of "real part",
1428 // but unlike them there is no meaningful notion of "imaginary part".
1429 // Instead there is an "unreal part" which itself is an octonion, and usually
1430 // nothing simpler (as opposed to the complex number case).
1431 // However, for practicallity, there are accessors for the other components
1432 // (these are necessary for the templated copy constructor, for instance).
1434 BOOST_OCTONION_ACCESSOR_GENERATOR(float)
1436 // assignment operators
1438 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float)
1440 // other assignment-related operators
1442 // NOTE: Octonion multiplication is *NOT* commutative;
1443 // symbolically, "q *= rhs;" means "q = q * rhs;"
1444 // and "q /= rhs;" means "q = q * inverse_of(rhs);";
1445 // octonion multiplication is also *NOT* associative
1447 BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float)
1452 BOOST_OCTONION_MEMBER_DATA_GENERATOR(float)
1461 class octonion
<double>
1465 typedef double value_type
;
1467 BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double)
1469 // UNtemplated copy constructor
1470 // (this is taken care of by the compiler itself)
1472 // converting copy constructor
1474 explicit octonion(octonion
<float> const & a_recopier
)
1476 *this = detail::octonion_type_converter
<double, float>(a_recopier
);
1479 // explicit copy constructors (precision-loosing converters)
1481 explicit octonion(octonion
<long double> const & a_recopier
)
1483 *this = detail::octonion_type_converter
<double, long double>(a_recopier
);
1487 // (this is taken care of by the compiler itself)
1491 // Note: Like complex number, octonions do have a meaningful notion of "real part",
1492 // but unlike them there is no meaningful notion of "imaginary part".
1493 // Instead there is an "unreal part" which itself is an octonion, and usually
1494 // nothing simpler (as opposed to the complex number case).
1495 // However, for practicallity, there are accessors for the other components
1496 // (these are necessary for the templated copy constructor, for instance).
1498 BOOST_OCTONION_ACCESSOR_GENERATOR(double)
1500 // assignment operators
1502 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double)
1504 // other assignment-related operators
1506 // NOTE: Octonion multiplication is *NOT* commutative;
1507 // symbolically, "q *= rhs;" means "q = q * rhs;"
1508 // and "q /= rhs;" means "q = q * inverse_of(rhs);";
1509 // octonion multiplication is also *NOT* associative
1511 BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double)
1516 BOOST_OCTONION_MEMBER_DATA_GENERATOR(double)
1525 class octonion
<long double>
1529 typedef long double value_type
;
1531 BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double)
1533 // UNtemplated copy constructor
1534 // (this is taken care of by the compiler itself)
1536 // converting copy constructor
1538 explicit octonion(octonion
<float> const & a_recopier
)
1540 *this = detail::octonion_type_converter
<long double, float>(a_recopier
);
1544 explicit octonion(octonion
<double> const & a_recopier
)
1546 *this = detail::octonion_type_converter
<long double, double>(a_recopier
);
1551 // (this is taken care of by the compiler itself)
1555 // Note: Like complex number, octonions do have a meaningful notion of "real part",
1556 // but unlike them there is no meaningful notion of "imaginary part".
1557 // Instead there is an "unreal part" which itself is an octonion, and usually
1558 // nothing simpler (as opposed to the complex number case).
1559 // However, for practicallity, there are accessors for the other components
1560 // (these are necessary for the templated copy constructor, for instance).
1562 BOOST_OCTONION_ACCESSOR_GENERATOR(long double)
1564 // assignment operators
1566 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double)
1568 // other assignment-related operators
1570 // NOTE: Octonion multiplication is *NOT* commutative;
1571 // symbolically, "q *= rhs;" means "q = q * rhs;"
1572 // and "q /= rhs;" means "q = q * inverse_of(rhs);";
1573 // octonion multiplication is also *NOT* associative
1575 BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double)
1580 BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double)
1588 #undef BOOST_OCTONION_CONSTRUCTOR_GENERATOR
1590 #undef BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR
1592 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR
1593 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR
1594 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR
1595 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR
1597 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_1
1598 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_2
1599 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_3
1600 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_4
1601 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_1
1602 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_2
1603 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_3
1604 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_4
1605 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_1
1606 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_2
1607 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_3
1608 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_4
1609 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_1
1610 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_2
1611 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_3
1612 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_4
1615 #undef BOOST_OCTONION_MEMBER_DATA_GENERATOR
1617 #undef BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR
1619 #undef BOOST_OCTONION_ACCESSOR_GENERATOR
1624 #define BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \
1626 octonion<T> res(lhs); \
1631 #define BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \
1632 template<typename T> \
1633 inline octonion<T> operator op (T const & lhs, octonion<T> const & rhs) \
1634 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1636 #define BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \
1637 template<typename T> \
1638 inline octonion<T> operator op (octonion<T> const & lhs, T const & rhs) \
1639 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1641 #define BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \
1642 template<typename T> \
1643 inline octonion<T> operator op (::std::complex<T> const & lhs, octonion<T> const & rhs) \
1644 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1646 #define BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \
1647 template<typename T> \
1648 inline octonion<T> operator op (octonion<T> const & lhs, ::std::complex<T> const & rhs) \
1649 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1651 #define BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \
1652 template<typename T> \
1653 inline octonion<T> operator op (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) \
1654 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1656 #define BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \
1657 template<typename T> \
1658 inline octonion<T> operator op (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) \
1659 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1661 #define BOOST_OCTONION_OPERATOR_GENERATOR_4(op) \
1662 template<typename T> \
1663 inline octonion<T> operator op (octonion<T> const & lhs, octonion<T> const & rhs) \
1664 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1666 #define BOOST_OCTONION_OPERATOR_GENERATOR(op) \
1667 BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \
1668 BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \
1669 BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \
1670 BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \
1671 BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \
1672 BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \
1673 BOOST_OCTONION_OPERATOR_GENERATOR_4(op)
1676 BOOST_OCTONION_OPERATOR_GENERATOR(+)
1677 BOOST_OCTONION_OPERATOR_GENERATOR(-)
1678 BOOST_OCTONION_OPERATOR_GENERATOR(*)
1679 BOOST_OCTONION_OPERATOR_GENERATOR(/)
1682 #undef BOOST_OCTONION_OPERATOR_GENERATOR
1684 #undef BOOST_OCTONION_OPERATOR_GENERATOR_1_L
1685 #undef BOOST_OCTONION_OPERATOR_GENERATOR_1_R
1686 #undef BOOST_OCTONION_OPERATOR_GENERATOR_2_L
1687 #undef BOOST_OCTONION_OPERATOR_GENERATOR_2_R
1688 #undef BOOST_OCTONION_OPERATOR_GENERATOR_3_L
1689 #undef BOOST_OCTONION_OPERATOR_GENERATOR_3_R
1690 #undef BOOST_OCTONION_OPERATOR_GENERATOR_4
1692 #undef BOOST_OCTONION_OPERATOR_GENERATOR_BODY
1695 template<typename T
>
1696 inline octonion
<T
> operator + (octonion
<T
> const & o
)
1702 template<typename T
>
1703 inline octonion
<T
> operator - (octonion
<T
> const & o
)
1705 return(octonion
<T
>(-o
.R_component_1(),-o
.R_component_2(),-o
.R_component_3(),-o
.R_component_4(),-o
.R_component_5(),-o
.R_component_6(),-o
.R_component_7(),-o
.R_component_8()));
1709 template<typename T
>
1710 inline bool operator == (T
const & lhs
, octonion
<T
> const & rhs
)
1713 (rhs
.R_component_1() == lhs
)&&
1714 (rhs
.R_component_2() == static_cast<T
>(0))&&
1715 (rhs
.R_component_3() == static_cast<T
>(0))&&
1716 (rhs
.R_component_4() == static_cast<T
>(0))&&
1717 (rhs
.R_component_5() == static_cast<T
>(0))&&
1718 (rhs
.R_component_6() == static_cast<T
>(0))&&
1719 (rhs
.R_component_7() == static_cast<T
>(0))&&
1720 (rhs
.R_component_8() == static_cast<T
>(0))
1725 template<typename T
>
1726 inline bool operator == (octonion
<T
> const & lhs
, T
const & rhs
)
1729 (lhs
.R_component_1() == rhs
)&&
1730 (lhs
.R_component_2() == static_cast<T
>(0))&&
1731 (lhs
.R_component_3() == static_cast<T
>(0))&&
1732 (lhs
.R_component_4() == static_cast<T
>(0))&&
1733 (lhs
.R_component_5() == static_cast<T
>(0))&&
1734 (lhs
.R_component_6() == static_cast<T
>(0))&&
1735 (lhs
.R_component_7() == static_cast<T
>(0))&&
1736 (lhs
.R_component_8() == static_cast<T
>(0))
1741 template<typename T
>
1742 inline bool operator == (::std::complex<T
> const & lhs
, octonion
<T
> const & rhs
)
1745 (rhs
.R_component_1() == lhs
.real())&&
1746 (rhs
.R_component_2() == lhs
.imag())&&
1747 (rhs
.R_component_3() == static_cast<T
>(0))&&
1748 (rhs
.R_component_4() == static_cast<T
>(0))&&
1749 (rhs
.R_component_5() == static_cast<T
>(0))&&
1750 (rhs
.R_component_6() == static_cast<T
>(0))&&
1751 (rhs
.R_component_7() == static_cast<T
>(0))&&
1752 (rhs
.R_component_8() == static_cast<T
>(0))
1757 template<typename T
>
1758 inline bool operator == (octonion
<T
> const & lhs
, ::std::complex<T
> const & rhs
)
1761 (lhs
.R_component_1() == rhs
.real())&&
1762 (lhs
.R_component_2() == rhs
.imag())&&
1763 (lhs
.R_component_3() == static_cast<T
>(0))&&
1764 (lhs
.R_component_4() == static_cast<T
>(0))&&
1765 (lhs
.R_component_5() == static_cast<T
>(0))&&
1766 (lhs
.R_component_6() == static_cast<T
>(0))&&
1767 (lhs
.R_component_7() == static_cast<T
>(0))&&
1768 (lhs
.R_component_8() == static_cast<T
>(0))
1773 template<typename T
>
1774 inline bool operator == (::boost::math::quaternion
<T
> const & lhs
, octonion
<T
> const & rhs
)
1777 (rhs
.R_component_1() == lhs
.R_component_1())&&
1778 (rhs
.R_component_2() == lhs
.R_component_2())&&
1779 (rhs
.R_component_3() == lhs
.R_component_3())&&
1780 (rhs
.R_component_4() == lhs
.R_component_4())&&
1781 (rhs
.R_component_5() == static_cast<T
>(0))&&
1782 (rhs
.R_component_6() == static_cast<T
>(0))&&
1783 (rhs
.R_component_7() == static_cast<T
>(0))&&
1784 (rhs
.R_component_8() == static_cast<T
>(0))
1789 template<typename T
>
1790 inline bool operator == (octonion
<T
> const & lhs
, ::boost::math::quaternion
<T
> const & rhs
)
1793 (lhs
.R_component_1() == rhs
.R_component_1())&&
1794 (lhs
.R_component_2() == rhs
.R_component_2())&&
1795 (lhs
.R_component_3() == rhs
.R_component_3())&&
1796 (lhs
.R_component_4() == rhs
.R_component_4())&&
1797 (lhs
.R_component_5() == static_cast<T
>(0))&&
1798 (lhs
.R_component_6() == static_cast<T
>(0))&&
1799 (lhs
.R_component_7() == static_cast<T
>(0))&&
1800 (lhs
.R_component_8() == static_cast<T
>(0))
1805 template<typename T
>
1806 inline bool operator == (octonion
<T
> const & lhs
, octonion
<T
> const & rhs
)
1809 (rhs
.R_component_1() == lhs
.R_component_1())&&
1810 (rhs
.R_component_2() == lhs
.R_component_2())&&
1811 (rhs
.R_component_3() == lhs
.R_component_3())&&
1812 (rhs
.R_component_4() == lhs
.R_component_4())&&
1813 (rhs
.R_component_5() == lhs
.R_component_5())&&
1814 (rhs
.R_component_6() == lhs
.R_component_6())&&
1815 (rhs
.R_component_7() == lhs
.R_component_7())&&
1816 (rhs
.R_component_8() == lhs
.R_component_8())
1821 #define BOOST_OCTONION_NOT_EQUAL_GENERATOR \
1823 return(!(lhs == rhs)); \
1826 template<typename T
>
1827 inline bool operator != (T
const & lhs
, octonion
<T
> const & rhs
)
1828 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1830 template<typename T
>
1831 inline bool operator != (octonion
<T
> const & lhs
, T
const & rhs
)
1832 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1834 template<typename T
>
1835 inline bool operator != (::std::complex<T
> const & lhs
, octonion
<T
> const & rhs
)
1836 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1838 template<typename T
>
1839 inline bool operator != (octonion
<T
> const & lhs
, ::std::complex<T
> const & rhs
)
1840 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1842 template<typename T
>
1843 inline bool operator != (::boost::math::quaternion
<T
> const & lhs
, octonion
<T
> const & rhs
)
1844 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1846 template<typename T
>
1847 inline bool operator != (octonion
<T
> const & lhs
, ::boost::math::quaternion
<T
> const & rhs
)
1848 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1850 template<typename T
>
1851 inline bool operator != (octonion
<T
> const & lhs
, octonion
<T
> const & rhs
)
1852 BOOST_OCTONION_NOT_EQUAL_GENERATOR
1854 #undef BOOST_OCTONION_NOT_EQUAL_GENERATOR
1857 // Note: the default values in the constructors of the complex and quaternions make for
1858 // a very complex and ambiguous situation; we have made choices to disambiguate.
1860 #if BOOST_WORKAROUND(__GNUC__, < 3)
1861 template<typename T
>
1862 ::std::istream
& operator >> ( ::std::istream
& is
,
1865 template<typename T
, typename charT
, class traits
>
1866 ::std::basic_istream
<charT
,traits
> & operator >> ( ::std::basic_istream
<charT
,traits
> & is
,
1868 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
1870 #if BOOST_WORKAROUND(__GNUC__, < 3)
1872 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
1874 #ifdef BOOST_NO_STD_LOCALE
1876 const ::std::ctype
<charT
> & ct
= ::std::use_facet
< ::std::ctype
<charT
> >(is
.getloc());
1877 #endif /* BOOST_NO_STD_LOCALE */
1888 ::std::complex<T
> u
= ::std::complex<T
>();
1889 ::std::complex<T
> v
= ::std::complex<T
>();
1890 ::std::complex<T
> x
= ::std::complex<T
>();
1891 ::std::complex<T
> y
= ::std::complex<T
>();
1893 ::boost::math::quaternion
<T
> p
= ::boost::math::quaternion
<T
>();
1894 ::boost::math::quaternion
<T
> q
= ::boost::math::quaternion
<T
>();
1899 is
>> ch
; // get the first lexeme
1901 if (!is
.good()) goto finish
;
1903 #ifdef BOOST_NO_STD_LOCALE
1906 cc
= ct
.narrow(ch
, char());
1907 #endif /* BOOST_NO_STD_LOCALE */
1909 if (cc
== '(') // read "("
1911 is
>> ch
; // get the second lexeme
1913 if (!is
.good()) goto finish
;
1915 #ifdef BOOST_NO_STD_LOCALE
1918 cc
= ct
.narrow(ch
, char());
1919 #endif /* BOOST_NO_STD_LOCALE */
1921 if (cc
== '(') // read "(("
1923 is
>> ch
; // get the third lexeme
1925 if (!is
.good()) goto finish
;
1927 #ifdef BOOST_NO_STD_LOCALE
1930 cc
= ct
.narrow(ch
, char());
1931 #endif /* BOOST_NO_STD_LOCALE */
1933 if (cc
== '(') // read "((("
1937 is
>> u
; // read "((u"
1939 if (!is
.good()) goto finish
;
1941 is
>> ch
; // get the next lexeme
1943 if (!is
.good()) goto finish
;
1945 #ifdef BOOST_NO_STD_LOCALE
1948 cc
= ct
.narrow(ch
, char());
1949 #endif /* BOOST_NO_STD_LOCALE */
1951 if (cc
== ')') // read "((u)"
1953 is
>> ch
; // get the next lexeme
1955 if (!is
.good()) goto finish
;
1957 #ifdef BOOST_NO_STD_LOCALE
1960 cc
= ct
.narrow(ch
, char());
1961 #endif /* BOOST_NO_STD_LOCALE */
1963 if (cc
== ')') // format: (((a))), (((a,b)))
1967 else if (cc
== ',') // read "((u),"
1969 p
= ::boost::math::quaternion
<T
>(u
);
1971 is
>> q
; // read "((u),q"
1973 if (!is
.good()) goto finish
;
1975 is
>> ch
; // get the next lexeme
1977 if (!is
.good()) goto finish
;
1979 #ifdef BOOST_NO_STD_LOCALE
1982 cc
= ct
.narrow(ch
, char());
1983 #endif /* BOOST_NO_STD_LOCALE */
1985 if (cc
== ')') // format: (((a)),q), (((a,b)),q)
1987 o
= octonion
<T
>(p
,q
);
1991 #if BOOST_WORKAROUND(__GNUC__, < 3)
1992 is
.setstate(::std::ios::failbit
);
1994 is
.setstate(::std::ios_base::failbit
);
1995 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2000 #if BOOST_WORKAROUND(__GNUC__, < 3)
2001 is
.setstate(::std::ios::failbit
);
2003 is
.setstate(::std::ios_base::failbit
);
2004 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2007 else if (cc
==',') // read "((u,"
2009 is
>> v
; // read "((u,v"
2011 if (!is
.good()) goto finish
;
2013 is
>> ch
; // get the next lexeme
2015 if (!is
.good()) goto finish
;
2017 #ifdef BOOST_NO_STD_LOCALE
2020 cc
= ct
.narrow(ch
, char());
2021 #endif /* BOOST_NO_STD_LOCALE */
2023 if (cc
== ')') // read "((u,v)"
2025 p
= ::boost::math::quaternion
<T
>(u
,v
);
2027 is
>> ch
; // get the next lexeme
2029 if (!is
.good()) goto finish
;
2031 #ifdef BOOST_NO_STD_LOCALE
2034 cc
= ct
.narrow(ch
, char());
2035 #endif /* BOOST_NO_STD_LOCALE */
2037 if (cc
== ')') // format: (((a),v)), (((a,b),v))
2041 else if (cc
== ',') // read "((u,v),"
2043 is
>> q
; // read "(p,q"
2045 if (!is
.good()) goto finish
;
2047 is
>> ch
; // get the next lexeme
2049 if (!is
.good()) goto finish
;
2051 #ifdef BOOST_NO_STD_LOCALE
2054 cc
= ct
.narrow(ch
, char());
2055 #endif /* BOOST_NO_STD_LOCALE */
2057 if (cc
== ')') // format: (((a),v),q), (((a,b),v),q)
2059 o
= octonion
<T
>(p
,q
);
2063 #if BOOST_WORKAROUND(__GNUC__, < 3)
2064 is
.setstate(::std::ios::failbit
);
2066 is
.setstate(::std::ios_base::failbit
);
2067 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2072 #if BOOST_WORKAROUND(__GNUC__, < 3)
2073 is
.setstate(::std::ios::failbit
);
2075 is
.setstate(::std::ios_base::failbit
);
2076 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2081 #if BOOST_WORKAROUND(__GNUC__, < 3)
2082 is
.setstate(::std::ios::failbit
);
2084 is
.setstate(::std::ios_base::failbit
);
2085 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2090 #if BOOST_WORKAROUND(__GNUC__, < 3)
2091 is
.setstate(::std::ios::failbit
);
2093 is
.setstate(::std::ios_base::failbit
);
2094 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2101 is
>> a
; // we extract the first component
2103 if (!is
.good()) goto finish
;
2105 is
>> ch
; // get the next lexeme
2107 if (!is
.good()) goto finish
;
2109 #ifdef BOOST_NO_STD_LOCALE
2112 cc
= ct
.narrow(ch
, char());
2113 #endif /* BOOST_NO_STD_LOCALE */
2115 if (cc
== ')') // read "((a)"
2117 is
>> ch
; // get the next lexeme
2119 if (!is
.good()) goto finish
;
2121 #ifdef BOOST_NO_STD_LOCALE
2124 cc
= ct
.narrow(ch
, char());
2125 #endif /* BOOST_NO_STD_LOCALE */
2127 if (cc
== ')') // read "((a))"
2131 else if (cc
== ',') // read "((a),"
2133 is
>> ch
; // get the next lexeme
2135 if (!is
.good()) goto finish
;
2137 #ifdef BOOST_NO_STD_LOCALE
2140 cc
= ct
.narrow(ch
, char());
2141 #endif /* BOOST_NO_STD_LOCALE */
2143 if (cc
== '(') // read "((a),("
2145 is
>> ch
; // get the next lexeme
2147 if (!is
.good()) goto finish
;
2149 #ifdef BOOST_NO_STD_LOCALE
2152 cc
= ct
.narrow(ch
, char());
2153 #endif /* BOOST_NO_STD_LOCALE */
2155 if (cc
== '(') // read "((a),(("
2159 is
.putback(ch
); // we backtrack twice, with the same value!
2161 is
>> q
; // read "((a),q"
2163 if (!is
.good()) goto finish
;
2165 is
>> ch
; // get the next lexeme
2167 if (!is
.good()) goto finish
;
2169 #ifdef BOOST_NO_STD_LOCALE
2172 cc
= ct
.narrow(ch
, char());
2173 #endif /* BOOST_NO_STD_LOCALE */
2175 if (cc
== ')') // read "((a),q)"
2177 p
= ::boost::math::quaternion
<T
>(a
);
2179 o
= octonion
<T
>(p
,q
);
2183 #if BOOST_WORKAROUND(__GNUC__, < 3)
2184 is
.setstate(::std::ios::failbit
);
2186 is
.setstate(::std::ios_base::failbit
);
2187 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2190 else // read "((a),(c" or "((a),(e"
2196 if (!is
.good()) goto finish
;
2198 is
>> ch
; // get the next lexeme
2200 if (!is
.good()) goto finish
;
2202 #ifdef BOOST_NO_STD_LOCALE
2205 cc
= ct
.narrow(ch
, char());
2206 #endif /* BOOST_NO_STD_LOCALE */
2208 if (cc
== ')') // read "((a),(c)" (ambiguity resolution)
2210 is
>> ch
; // get the next lexeme
2212 if (!is
.good()) goto finish
;
2214 #ifdef BOOST_NO_STD_LOCALE
2217 cc
= ct
.narrow(ch
, char());
2218 #endif /* BOOST_NO_STD_LOCALE */
2220 if (cc
== ')') // read "((a),(c))"
2222 o
= octonion
<T
>(a
,b
,c
);
2224 else if (cc
== ',') // read "((a),(c),"
2226 u
= ::std::complex<T
>(a
);
2228 v
= ::std::complex<T
>(c
);
2230 is
>> x
; // read "((a),(c),x"
2232 if (!is
.good()) goto finish
;
2234 is
>> ch
; // get the next lexeme
2236 if (!is
.good()) goto finish
;
2238 #ifdef BOOST_NO_STD_LOCALE
2241 cc
= ct
.narrow(ch
, char());
2242 #endif /* BOOST_NO_STD_LOCALE */
2244 if (cc
== ')') // read "((a),(c),x)"
2246 o
= octonion
<T
>(u
,v
,x
);
2248 else if (cc
== ',') // read "((a),(c),x,"
2250 is
>> y
; // read "((a),(c),x,y"
2252 if (!is
.good()) goto finish
;
2254 is
>> ch
; // get the next lexeme
2256 if (!is
.good()) goto finish
;
2258 #ifdef BOOST_NO_STD_LOCALE
2261 cc
= ct
.narrow(ch
, char());
2262 #endif /* BOOST_NO_STD_LOCALE */
2264 if (cc
== ')') // read "((a),(c),x,y)"
2266 o
= octonion
<T
>(u
,v
,x
,y
);
2270 #if BOOST_WORKAROUND(__GNUC__, < 3)
2271 is
.setstate(::std::ios::failbit
);
2273 is
.setstate(::std::ios_base::failbit
);
2274 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2279 #if BOOST_WORKAROUND(__GNUC__, < 3)
2280 is
.setstate(::std::ios::failbit
);
2282 is
.setstate(::std::ios_base::failbit
);
2283 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2288 #if BOOST_WORKAROUND(__GNUC__, < 3)
2289 is
.setstate(::std::ios::failbit
);
2291 is
.setstate(::std::ios_base::failbit
);
2292 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2295 else if (cc
== ',') // read "((a),(c," or "((a),(e,"
2297 is
>> ch
; // get the next lexeme
2299 if (!is
.good()) goto finish
;
2301 #ifdef BOOST_NO_STD_LOCALE
2304 cc
= ct
.narrow(ch
, char());
2305 #endif /* BOOST_NO_STD_LOCALE */
2307 if (cc
== '(') // read "((a),(e,(" (ambiguity resolution)
2309 p
= ::boost::math::quaternion
<T
>(a
);
2311 x
= ::std::complex<T
>(c
); // "c" was actually "e"
2313 is
.putback(ch
); // we can only backtrace once
2315 is
>> y
; // read "((a),(e,y"
2317 if (!is
.good()) goto finish
;
2319 is
>> ch
; // get the next lexeme
2321 #ifdef BOOST_NO_STD_LOCALE
2324 cc
= ct
.narrow(ch
, char());
2325 #endif /* BOOST_NO_STD_LOCALE */
2327 if (cc
== ')') // read "((a),(e,y)"
2329 q
= ::boost::math::quaternion
<T
>(x
,y
);
2331 is
>> ch
; // get the next lexeme
2333 #ifdef BOOST_NO_STD_LOCALE
2336 cc
= ct
.narrow(ch
, char());
2337 #endif /* BOOST_NO_STD_LOCALE */
2339 if (cc
== ')') // read "((a),(e,y))"
2341 o
= octonion
<T
>(p
,q
);
2345 #if BOOST_WORKAROUND(__GNUC__, < 3)
2346 is
.setstate(::std::ios::failbit
);
2348 is
.setstate(::std::ios_base::failbit
);
2349 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2354 #if BOOST_WORKAROUND(__GNUC__, < 3)
2355 is
.setstate(::std::ios::failbit
);
2357 is
.setstate(::std::ios_base::failbit
);
2358 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2361 else // read "((a),(c,d" or "((a),(e,f"
2367 if (!is
.good()) goto finish
;
2369 is
>> ch
; // get the next lexeme
2371 if (!is
.good()) goto finish
;
2373 #ifdef BOOST_NO_STD_LOCALE
2376 cc
= ct
.narrow(ch
, char());
2377 #endif /* BOOST_NO_STD_LOCALE */
2379 if (cc
== ')') // read "((a),(c,d)" (ambiguity resolution)
2381 is
>> ch
; // get the next lexeme
2383 if (!is
.good()) goto finish
;
2385 #ifdef BOOST_NO_STD_LOCALE
2388 cc
= ct
.narrow(ch
, char());
2389 #endif /* BOOST_NO_STD_LOCALE */
2391 if (cc
== ')') // read "((a),(c,d))"
2393 o
= octonion
<T
>(a
,b
,c
,d
);
2395 else if (cc
== ',') // read "((a),(c,d),"
2397 u
= ::std::complex<T
>(a
);
2399 v
= ::std::complex<T
>(c
,d
);
2401 is
>> x
; // read "((a),(c,d),x"
2403 if (!is
.good()) goto finish
;
2405 is
>> ch
; // get the next lexeme
2407 if (!is
.good()) goto finish
;
2409 #ifdef BOOST_NO_STD_LOCALE
2412 cc
= ct
.narrow(ch
, char());
2413 #endif /* BOOST_NO_STD_LOCALE */
2415 if (cc
== ')') // read "((a),(c,d),x)"
2417 o
= octonion
<T
>(u
,v
,x
);
2419 else if (cc
== ',') // read "((a),(c,d),x,"
2421 is
>> y
; // read "((a),(c,d),x,y"
2423 if (!is
.good()) goto finish
;
2425 is
>> ch
; // get the next lexeme
2427 if (!is
.good()) goto finish
;
2429 #ifdef BOOST_NO_STD_LOCALE
2432 cc
= ct
.narrow(ch
, char());
2433 #endif /* BOOST_NO_STD_LOCALE */
2435 if (cc
== ')') // read "((a),(c,d),x,y)"
2437 o
= octonion
<T
>(u
,v
,x
,y
);
2441 #if BOOST_WORKAROUND(__GNUC__, < 3)
2442 is
.setstate(::std::ios::failbit
);
2444 is
.setstate(::std::ios_base::failbit
);
2445 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2450 #if BOOST_WORKAROUND(__GNUC__, < 3)
2451 is
.setstate(::std::ios::failbit
);
2453 is
.setstate(::std::ios_base::failbit
);
2454 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2459 #if BOOST_WORKAROUND(__GNUC__, < 3)
2460 is
.setstate(::std::ios::failbit
);
2462 is
.setstate(::std::ios_base::failbit
);
2463 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2466 else if (cc
== ',') // read "((a),(e,f," (ambiguity resolution)
2468 p
= ::boost::math::quaternion
<T
>(a
);
2470 is
>> g
; // read "((a),(e,f,g" (too late to backtrack)
2472 if (!is
.good()) goto finish
;
2474 is
>> ch
; // get the next lexeme
2476 if (!is
.good()) goto finish
;
2478 #ifdef BOOST_NO_STD_LOCALE
2481 cc
= ct
.narrow(ch
, char());
2482 #endif /* BOOST_NO_STD_LOCALE */
2484 if (cc
== ')') // read "((a),(e,f,g)"
2486 q
= ::boost::math::quaternion
<T
>(c
,d
,g
); // "c" was actually "e", and "d" was actually "f"
2488 is
>> ch
; // get the next lexeme
2490 if (!is
.good()) goto finish
;
2492 #ifdef BOOST_NO_STD_LOCALE
2495 cc
= ct
.narrow(ch
, char());
2496 #endif /* BOOST_NO_STD_LOCALE */
2498 if (cc
== ')') // read "((a),(e,f,g))"
2500 o
= octonion
<T
>(p
,q
);
2504 #if BOOST_WORKAROUND(__GNUC__, < 3)
2505 is
.setstate(::std::ios::failbit
);
2507 is
.setstate(::std::ios_base::failbit
);
2508 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2511 else if (cc
== ',') // read "((a),(e,f,g,"
2513 is
>> h
; // read "((a),(e,f,g,h"
2515 if (!is
.good()) goto finish
;
2517 is
>> ch
; // get the next lexeme
2519 if (!is
.good()) goto finish
;
2521 #ifdef BOOST_NO_STD_LOCALE
2524 cc
= ct
.narrow(ch
, char());
2525 #endif /* BOOST_NO_STD_LOCALE */
2527 if (cc
== ')') // read "((a),(e,f,g,h)"
2529 q
= ::boost::math::quaternion
<T
>(c
,d
,g
,h
); // "c" was actually "e", and "d" was actually "f"
2531 is
>> ch
; // get the next lexeme
2533 if (!is
.good()) goto finish
;
2535 #ifdef BOOST_NO_STD_LOCALE
2538 cc
= ct
.narrow(ch
, char());
2539 #endif /* BOOST_NO_STD_LOCALE */
2541 if (cc
== ')') // read "((a),(e,f,g,h))"
2543 o
= octonion
<T
>(p
,q
);
2547 #if BOOST_WORKAROUND(__GNUC__, < 3)
2548 is
.setstate(::std::ios::failbit
);
2550 is
.setstate(::std::ios_base::failbit
);
2551 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2556 #if BOOST_WORKAROUND(__GNUC__, < 3)
2557 is
.setstate(::std::ios::failbit
);
2559 is
.setstate(::std::ios_base::failbit
);
2560 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2565 #if BOOST_WORKAROUND(__GNUC__, < 3)
2566 is
.setstate(::std::ios::failbit
);
2568 is
.setstate(::std::ios_base::failbit
);
2569 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2574 #if BOOST_WORKAROUND(__GNUC__, < 3)
2575 is
.setstate(::std::ios::failbit
);
2577 is
.setstate(::std::ios_base::failbit
);
2578 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2584 #if BOOST_WORKAROUND(__GNUC__, < 3)
2585 is
.setstate(::std::ios::failbit
);
2587 is
.setstate(::std::ios_base::failbit
);
2588 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2592 else // read "((a),c" (ambiguity resolution)
2596 is
>> c
; // we extract the third component
2598 if (!is
.good()) goto finish
;
2600 is
>> ch
; // get the next lexeme
2602 if (!is
.good()) goto finish
;
2604 #ifdef BOOST_NO_STD_LOCALE
2607 cc
= ct
.narrow(ch
, char());
2608 #endif /* BOOST_NO_STD_LOCALE */
2610 if (cc
== ')') // read "((a),c)"
2612 o
= octonion
<T
>(a
,b
,c
);
2614 else if (cc
== ',') // read "((a),c,"
2616 is
>> x
; // read "((a),c,x"
2618 if (!is
.good()) goto finish
;
2620 is
>> ch
; // get the next lexeme
2622 if (!is
.good()) goto finish
;
2624 #ifdef BOOST_NO_STD_LOCALE
2627 cc
= ct
.narrow(ch
, char());
2628 #endif /* BOOST_NO_STD_LOCALE */
2630 if (cc
== ')') // read "((a),c,x)"
2632 o
= octonion
<T
>(a
,b
,c
,d
,x
.real(),x
.imag());
2634 else if (cc
== ',') // read "((a),c,x,"
2636 is
>> y
;if (!is
.good()) goto finish
; // read "((a),c,x,y"
2638 is
>> ch
; // get the next lexeme
2640 if (!is
.good()) goto finish
;
2642 #ifdef BOOST_NO_STD_LOCALE
2645 cc
= ct
.narrow(ch
, char());
2646 #endif /* BOOST_NO_STD_LOCALE */
2648 if (cc
== ')') // read "((a),c,x,y)"
2650 o
= octonion
<T
>(a
,b
,c
,d
,x
.real(),x
.imag(),y
.real(),y
.imag());
2654 #if BOOST_WORKAROUND(__GNUC__, < 3)
2655 is
.setstate(::std::ios::failbit
);
2657 is
.setstate(::std::ios_base::failbit
);
2658 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2663 #if BOOST_WORKAROUND(__GNUC__, < 3)
2664 is
.setstate(::std::ios::failbit
);
2666 is
.setstate(::std::ios_base::failbit
);
2667 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2672 #if BOOST_WORKAROUND(__GNUC__, < 3)
2673 is
.setstate(::std::ios::failbit
);
2675 is
.setstate(::std::ios_base::failbit
);
2676 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2682 #if BOOST_WORKAROUND(__GNUC__, < 3)
2683 is
.setstate(::std::ios::failbit
);
2685 is
.setstate(::std::ios_base::failbit
);
2686 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2689 else if (cc
==',') // read "((a,"
2691 is
>> ch
; // get the next lexeme
2693 if (!is
.good()) goto finish
;
2695 #ifdef BOOST_NO_STD_LOCALE
2698 cc
= ct
.narrow(ch
, char());
2699 #endif /* BOOST_NO_STD_LOCALE */
2701 if (cc
== '(') // read "((a,("
2703 u
= ::std::complex<T
>(a
);
2705 is
.putback(ch
); // can only backtrack so much
2707 is
>> v
; // read "((a,v"
2709 if (!is
.good()) goto finish
;
2711 is
>> ch
; // get the next lexeme
2713 if (!is
.good()) goto finish
;
2715 #ifdef BOOST_NO_STD_LOCALE
2718 cc
= ct
.narrow(ch
, char());
2719 #endif /* BOOST_NO_STD_LOCALE */
2721 if (cc
== ')') // read "((a,v)"
2723 is
>> ch
; // get the next lexeme
2725 if (!is
.good()) goto finish
;
2727 #ifdef BOOST_NO_STD_LOCALE
2730 cc
= ct
.narrow(ch
, char());
2731 #endif /* BOOST_NO_STD_LOCALE */
2733 if (cc
== ')') // read "((a,v))"
2735 o
= octonion
<T
>(u
,v
);
2737 else if (cc
== ',') // read "((a,v),"
2739 p
= ::boost::math::quaternion
<T
>(u
,v
);
2741 is
>> q
; // read "((a,v),q"
2743 if (!is
.good()) goto finish
;
2745 is
>> ch
; // get the next lexeme
2747 if (!is
.good()) goto finish
;
2749 #ifdef BOOST_NO_STD_LOCALE
2752 cc
= ct
.narrow(ch
, char());
2753 #endif /* BOOST_NO_STD_LOCALE */
2755 if (cc
== ')') // read "((a,v),q)"
2757 o
= octonion
<T
>(p
,q
);
2761 #if BOOST_WORKAROUND(__GNUC__, < 3)
2762 is
.setstate(::std::ios::failbit
);
2764 is
.setstate(::std::ios_base::failbit
);
2765 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2770 #if BOOST_WORKAROUND(__GNUC__, < 3)
2771 is
.setstate(::std::ios::failbit
);
2773 is
.setstate(::std::ios_base::failbit
);
2774 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2779 #if BOOST_WORKAROUND(__GNUC__, < 3)
2780 is
.setstate(::std::ios::failbit
);
2782 is
.setstate(::std::ios_base::failbit
);
2783 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2790 is
>> b
; // read "((a,b"
2792 if (!is
.good()) goto finish
;
2794 is
>> ch
; // get the next lexeme
2796 if (!is
.good()) goto finish
;
2798 #ifdef BOOST_NO_STD_LOCALE
2801 cc
= ct
.narrow(ch
, char());
2802 #endif /* BOOST_NO_STD_LOCALE */
2804 if (cc
== ')') // read "((a,b)"
2806 is
>> ch
; // get the next lexeme
2808 if (!is
.good()) goto finish
;
2810 #ifdef BOOST_NO_STD_LOCALE
2813 cc
= ct
.narrow(ch
, char());
2814 #endif /* BOOST_NO_STD_LOCALE */
2816 if (cc
== ')') // read "((a,b))"
2818 o
= octonion
<T
>(a
,b
);
2820 else if (cc
== ',') // read "((a,b),"
2822 is
>> ch
; // get the next lexeme
2824 if (!is
.good()) goto finish
;
2826 #ifdef BOOST_NO_STD_LOCALE
2829 cc
= ct
.narrow(ch
, char());
2830 #endif /* BOOST_NO_STD_LOCALE */
2832 if (cc
== '(') // read "((a,b),("
2834 is
>> ch
; // get the next lexeme
2836 if (!is
.good()) goto finish
;
2838 #ifdef BOOST_NO_STD_LOCALE
2841 cc
= ct
.narrow(ch
, char());
2842 #endif /* BOOST_NO_STD_LOCALE */
2844 if (cc
== '(') // read "((a,b),(("
2846 p
= ::boost::math::quaternion
<T
>(a
,b
);
2850 is
.putback(ch
); // we backtrack twice, with the same value
2852 is
>> q
; // read "((a,b),q"
2854 if (!is
.good()) goto finish
;
2856 is
>> ch
; // get the next lexeme
2858 if (!is
.good()) goto finish
;
2860 #ifdef BOOST_NO_STD_LOCALE
2863 cc
= ct
.narrow(ch
, char());
2864 #endif /* BOOST_NO_STD_LOCALE */
2866 if (cc
== ')') // read "((a,b),q)"
2868 o
= octonion
<T
>(p
,q
);
2872 #if BOOST_WORKAROUND(__GNUC__, < 3)
2873 is
.setstate(::std::ios::failbit
);
2875 is
.setstate(::std::ios_base::failbit
);
2876 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2879 else // read "((a,b),(c" or "((a,b),(e"
2885 if (!is
.good()) goto finish
;
2887 is
>> ch
; // get the next lexeme
2889 if (!is
.good()) goto finish
;
2891 #ifdef BOOST_NO_STD_LOCALE
2894 cc
= ct
.narrow(ch
, char());
2895 #endif /* BOOST_NO_STD_LOCALE */
2897 if (cc
== ')') // read "((a,b),(c)" (ambiguity resolution)
2899 is
>> ch
; // get the next lexeme
2901 if (!is
.good()) goto finish
;
2903 #ifdef BOOST_NO_STD_LOCALE
2906 cc
= ct
.narrow(ch
, char());
2907 #endif /* BOOST_NO_STD_LOCALE */
2909 if (cc
== ')') // read "((a,b),(c))"
2911 o
= octonion
<T
>(a
,b
,c
);
2913 else if (cc
== ',') // read "((a,b),(c),"
2915 u
= ::std::complex<T
>(a
,b
);
2917 v
= ::std::complex<T
>(c
);
2919 is
>> x
; // read "((a,b),(c),x"
2921 if (!is
.good()) goto finish
;
2923 is
>> ch
; // get the next lexeme
2925 if (!is
.good()) goto finish
;
2927 #ifdef BOOST_NO_STD_LOCALE
2930 cc
= ct
.narrow(ch
, char());
2931 #endif /* BOOST_NO_STD_LOCALE */
2933 if (cc
== ')') // read "((a,b),(c),x)"
2935 o
= octonion
<T
>(u
,v
,x
);
2937 else if (cc
== ',') // read "((a,b),(c),x,"
2939 is
>> y
; // read "((a,b),(c),x,y"
2941 if (!is
.good()) goto finish
;
2943 is
>> ch
; // get the next lexeme
2945 if (!is
.good()) goto finish
;
2947 #ifdef BOOST_NO_STD_LOCALE
2950 cc
= ct
.narrow(ch
, char());
2951 #endif /* BOOST_NO_STD_LOCALE */
2953 if (cc
== ')') // read "((a,b),(c),x,y)"
2955 o
= octonion
<T
>(u
,v
,x
,y
);
2959 #if BOOST_WORKAROUND(__GNUC__, < 3)
2960 is
.setstate(::std::ios::failbit
);
2962 is
.setstate(::std::ios_base::failbit
);
2963 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2968 #if BOOST_WORKAROUND(__GNUC__, < 3)
2969 is
.setstate(::std::ios::failbit
);
2971 is
.setstate(::std::ios_base::failbit
);
2972 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2977 #if BOOST_WORKAROUND(__GNUC__, < 3)
2978 is
.setstate(::std::ios::failbit
);
2980 is
.setstate(::std::ios_base::failbit
);
2981 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
2984 else if (cc
== ',') // read "((a,b),(c," or "((a,b),(e,"
2986 is
>> ch
; // get the next lexeme
2988 if (!is
.good()) goto finish
;
2990 #ifdef BOOST_NO_STD_LOCALE
2993 cc
= ct
.narrow(ch
, char());
2994 #endif /* BOOST_NO_STD_LOCALE */
2996 if (cc
== '(') // read "((a,b),(e,(" (ambiguity resolution)
2998 u
= ::std::complex<T
>(a
,b
);
3000 x
= ::std::complex<T
>(c
); // "c" is actually "e"
3004 is
>> y
; // read "((a,b),(e,y"
3006 if (!is
.good()) goto finish
;
3008 is
>> ch
; // get the next lexeme
3010 if (!is
.good()) goto finish
;
3012 #ifdef BOOST_NO_STD_LOCALE
3015 cc
= ct
.narrow(ch
, char());
3016 #endif /* BOOST_NO_STD_LOCALE */
3018 if (cc
== ')') // read "((a,b),(e,y)"
3020 is
>> ch
; // get the next lexeme
3022 if (!is
.good()) goto finish
;
3024 #ifdef BOOST_NO_STD_LOCALE
3027 cc
= ct
.narrow(ch
, char());
3028 #endif /* BOOST_NO_STD_LOCALE */
3030 if (cc
== ')') // read "((a,b),(e,y))"
3032 o
= octonion
<T
>(u
,v
,x
,y
);
3036 #if BOOST_WORKAROUND(__GNUC__, < 3)
3037 is
.setstate(::std::ios::failbit
);
3039 is
.setstate(::std::ios_base::failbit
);
3040 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3045 #if BOOST_WORKAROUND(__GNUC__, < 3)
3046 is
.setstate(::std::ios::failbit
);
3048 is
.setstate(::std::ios_base::failbit
);
3049 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3052 else // read "((a,b),(c,d" or "((a,b),(e,f"
3058 if (!is
.good()) goto finish
;
3060 is
>> ch
; // get the next lexeme
3062 if (!is
.good()) goto finish
;
3064 #ifdef BOOST_NO_STD_LOCALE
3067 cc
= ct
.narrow(ch
, char());
3068 #endif /* BOOST_NO_STD_LOCALE */
3070 if (cc
== ')') // read "((a,b),(c,d)" (ambiguity resolution)
3072 u
= ::std::complex<T
>(a
,b
);
3074 v
= ::std::complex<T
>(c
,d
);
3076 is
>> ch
; // get the next lexeme
3078 if (!is
.good()) goto finish
;
3080 #ifdef BOOST_NO_STD_LOCALE
3083 cc
= ct
.narrow(ch
, char());
3084 #endif /* BOOST_NO_STD_LOCALE */
3086 if (cc
== ')') // read "((a,b),(c,d))"
3088 o
= octonion
<T
>(u
,v
);
3090 else if (cc
== ',') // read "((a,b),(c,d),"
3092 is
>> x
; // read "((a,b),(c,d),x
3094 if (!is
.good()) goto finish
;
3096 is
>> ch
; // get the next lexeme
3098 if (!is
.good()) goto finish
;
3100 #ifdef BOOST_NO_STD_LOCALE
3103 cc
= ct
.narrow(ch
, char());
3104 #endif /* BOOST_NO_STD_LOCALE */
3106 if (cc
== ')') // read "((a,b),(c,d),x)"
3108 o
= octonion
<T
>(u
,v
,x
);
3110 else if (cc
== ',') // read "((a,b),(c,d),x,"
3112 is
>> y
; // read "((a,b),(c,d),x,y"
3114 if (!is
.good()) goto finish
;
3116 is
>> ch
; // get the next lexeme
3118 if (!is
.good()) goto finish
;
3120 #ifdef BOOST_NO_STD_LOCALE
3123 cc
= ct
.narrow(ch
, char());
3124 #endif /* BOOST_NO_STD_LOCALE */
3126 if (cc
== ')') // read "((a,b),(c,d),x,y)"
3128 o
= octonion
<T
>(u
,v
,x
,y
);
3132 #if BOOST_WORKAROUND(__GNUC__, < 3)
3133 is
.setstate(::std::ios::failbit
);
3135 is
.setstate(::std::ios_base::failbit
);
3136 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3141 #if BOOST_WORKAROUND(__GNUC__, < 3)
3142 is
.setstate(::std::ios::failbit
);
3144 is
.setstate(::std::ios_base::failbit
);
3145 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3150 #if BOOST_WORKAROUND(__GNUC__, < 3)
3151 is
.setstate(::std::ios::failbit
);
3153 is
.setstate(::std::ios_base::failbit
);
3154 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3157 else if (cc
== ',') // read "((a,b),(e,f," (ambiguity resolution)
3159 p
= ::boost::math::quaternion
<T
>(a
,b
); // too late to backtrack
3161 is
>> g
; // read "((a,b),(e,f,g"
3163 if (!is
.good()) goto finish
;
3165 is
>> ch
; // get the next lexeme
3167 if (!is
.good()) goto finish
;
3169 #ifdef BOOST_NO_STD_LOCALE
3172 cc
= ct
.narrow(ch
, char());
3173 #endif /* BOOST_NO_STD_LOCALE */
3175 if (cc
== ')') // read "((a,b),(e,f,g)"
3177 is
>> ch
; // get the next lexeme
3179 if (!is
.good()) goto finish
;
3181 #ifdef BOOST_NO_STD_LOCALE
3184 cc
= ct
.narrow(ch
, char());
3185 #endif /* BOOST_NO_STD_LOCALE */
3187 if (cc
== ')') // read "((a,b),(e,f,g))"
3189 q
= ::boost::math::quaternion
<T
>(c
,d
,g
); // "c" is actually "e" and "d" is actually "f"
3191 o
= octonion
<T
>(p
,q
);
3195 #if BOOST_WORKAROUND(__GNUC__, < 3)
3196 is
.setstate(::std::ios::failbit
);
3198 is
.setstate(::std::ios_base::failbit
);
3199 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3202 else if (cc
== ',') // read "((a,b),(e,f,g,"
3204 is
>> h
; // read "((a,b),(e,f,g,h"
3206 if (!is
.good()) goto finish
;
3208 is
>> ch
; // get the next lexeme
3210 if (!is
.good()) goto finish
;
3212 #ifdef BOOST_NO_STD_LOCALE
3215 cc
= ct
.narrow(ch
, char());
3216 #endif /* BOOST_NO_STD_LOCALE */
3218 if (cc
== ')') // read "((a,b),(e,f,g,h)"
3220 is
>> ch
; // get the next lexeme
3222 if (!is
.good()) goto finish
;
3224 #ifdef BOOST_NO_STD_LOCALE
3227 cc
= ct
.narrow(ch
, char());
3228 #endif /* BOOST_NO_STD_LOCALE */
3230 if (cc
== ')') // read ((a,b),(e,f,g,h))"
3232 q
= ::boost::math::quaternion
<T
>(c
,d
,g
,h
); // "c" is actually "e" and "d" is actually "f"
3234 o
= octonion
<T
>(p
,q
);
3238 #if BOOST_WORKAROUND(__GNUC__, < 3)
3239 is
.setstate(::std::ios::failbit
);
3241 is
.setstate(::std::ios_base::failbit
);
3242 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3247 #if BOOST_WORKAROUND(__GNUC__, < 3)
3248 is
.setstate(::std::ios::failbit
);
3250 is
.setstate(::std::ios_base::failbit
);
3251 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3256 #if BOOST_WORKAROUND(__GNUC__, < 3)
3257 is
.setstate(::std::ios::failbit
);
3259 is
.setstate(::std::ios_base::failbit
);
3260 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3265 #if BOOST_WORKAROUND(__GNUC__, < 3)
3266 is
.setstate(::std::ios::failbit
);
3268 is
.setstate(::std::ios_base::failbit
);
3269 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3275 #if BOOST_WORKAROUND(__GNUC__, < 3)
3276 is
.setstate(::std::ios::failbit
);
3278 is
.setstate(::std::ios_base::failbit
);
3279 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3285 #if BOOST_WORKAROUND(__GNUC__, < 3)
3286 is
.setstate(::std::ios::failbit
);
3288 is
.setstate(::std::ios_base::failbit
);
3289 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3294 #if BOOST_WORKAROUND(__GNUC__, < 3)
3295 is
.setstate(::std::ios::failbit
);
3297 is
.setstate(::std::ios_base::failbit
);
3298 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3301 else if (cc
== ',') // read "((a,b,"
3303 is
>> c
; // read "((a,b,c"
3305 if (!is
.good()) goto finish
;
3307 is
>> ch
; // get the next lexeme
3309 if (!is
.good()) goto finish
;
3311 #ifdef BOOST_NO_STD_LOCALE
3314 cc
= ct
.narrow(ch
, char());
3315 #endif /* BOOST_NO_STD_LOCALE */
3317 if (cc
== ')') // read "((a,b,c)"
3319 is
>> ch
; // get the next lexeme
3321 if (!is
.good()) goto finish
;
3323 #ifdef BOOST_NO_STD_LOCALE
3326 cc
= ct
.narrow(ch
, char());
3327 #endif /* BOOST_NO_STD_LOCALE */
3329 if (cc
== ')') // read "((a,b,c))"
3331 o
= octonion
<T
>(a
,b
,c
);
3333 else if (cc
== ',') // read "((a,b,c),"
3335 p
= ::boost::math::quaternion
<T
>(a
,b
,c
);
3337 is
>> q
; // read "((a,b,c),q"
3339 if (!is
.good()) goto finish
;
3341 is
>> ch
; // get the next lexeme
3343 if (!is
.good()) goto finish
;
3345 #ifdef BOOST_NO_STD_LOCALE
3348 cc
= ct
.narrow(ch
, char());
3349 #endif /* BOOST_NO_STD_LOCALE */
3351 if (cc
== ')') // read "((a,b,c),q)"
3353 o
= octonion
<T
>(p
,q
);
3357 #if BOOST_WORKAROUND(__GNUC__, < 3)
3358 is
.setstate(::std::ios::failbit
);
3360 is
.setstate(::std::ios_base::failbit
);
3361 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3366 #if BOOST_WORKAROUND(__GNUC__, < 3)
3367 is
.setstate(::std::ios::failbit
);
3369 is
.setstate(::std::ios_base::failbit
);
3370 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3373 else if (cc
== ',') // read "((a,b,c,"
3375 is
>> d
; // read "((a,b,c,d"
3377 if (!is
.good()) goto finish
;
3379 is
>> ch
; // get the next lexeme
3381 if (!is
.good()) goto finish
;
3383 #ifdef BOOST_NO_STD_LOCALE
3386 cc
= ct
.narrow(ch
, char());
3387 #endif /* BOOST_NO_STD_LOCALE */
3389 if (cc
== ')') // read "((a,b,c,d)"
3391 is
>> ch
; // get the next lexeme
3393 if (!is
.good()) goto finish
;
3395 #ifdef BOOST_NO_STD_LOCALE
3398 cc
= ct
.narrow(ch
, char());
3399 #endif /* BOOST_NO_STD_LOCALE */
3401 if (cc
== ')') // read "((a,b,c,d))"
3403 o
= octonion
<T
>(a
,b
,c
,d
);
3405 else if (cc
== ',') // read "((a,b,c,d),"
3407 p
= ::boost::math::quaternion
<T
>(a
,b
,c
,d
);
3409 is
>> q
; // read "((a,b,c,d),q"
3411 if (!is
.good()) goto finish
;
3413 is
>> ch
; // get the next lexeme
3415 if (!is
.good()) goto finish
;
3417 #ifdef BOOST_NO_STD_LOCALE
3420 cc
= ct
.narrow(ch
, char());
3421 #endif /* BOOST_NO_STD_LOCALE */
3423 if (cc
== ')') // read "((a,b,c,d),q)"
3425 o
= octonion
<T
>(p
,q
);
3429 #if BOOST_WORKAROUND(__GNUC__, < 3)
3430 is
.setstate(::std::ios::failbit
);
3432 is
.setstate(::std::ios_base::failbit
);
3433 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3438 #if BOOST_WORKAROUND(__GNUC__, < 3)
3439 is
.setstate(::std::ios::failbit
);
3441 is
.setstate(::std::ios_base::failbit
);
3442 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3447 #if BOOST_WORKAROUND(__GNUC__, < 3)
3448 is
.setstate(::std::ios::failbit
);
3450 is
.setstate(::std::ios_base::failbit
);
3451 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3456 #if BOOST_WORKAROUND(__GNUC__, < 3)
3457 is
.setstate(::std::ios::failbit
);
3459 is
.setstate(::std::ios_base::failbit
);
3460 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3465 #if BOOST_WORKAROUND(__GNUC__, < 3)
3466 is
.setstate(::std::ios::failbit
);
3468 is
.setstate(::std::ios_base::failbit
);
3469 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3475 #if BOOST_WORKAROUND(__GNUC__, < 3)
3476 is
.setstate(::std::ios::failbit
);
3478 is
.setstate(::std::ios_base::failbit
);
3479 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3487 is
>> a
; // we extract the first component
3489 if (!is
.good()) goto finish
;
3491 is
>> ch
; // get the next lexeme
3493 if (!is
.good()) goto finish
;
3495 #ifdef BOOST_NO_STD_LOCALE
3498 cc
= ct
.narrow(ch
, char());
3499 #endif /* BOOST_NO_STD_LOCALE */
3501 if (cc
== ')') // read "(a)"
3505 else if (cc
== ',') // read "(a,"
3507 is
>> ch
; // get the next lexeme
3509 if (!is
.good()) goto finish
;
3511 #ifdef BOOST_NO_STD_LOCALE
3514 cc
= ct
.narrow(ch
, char());
3515 #endif /* BOOST_NO_STD_LOCALE */
3517 if (cc
== '(') // read "(a,("
3519 is
>> ch
; // get the next lexeme
3521 if (!is
.good()) goto finish
;
3523 #ifdef BOOST_NO_STD_LOCALE
3526 cc
= ct
.narrow(ch
, char());
3527 #endif /* BOOST_NO_STD_LOCALE */
3529 if (cc
== '(') // read "(a,(("
3531 p
= ::boost::math::quaternion
<T
>(a
);
3535 is
.putback(ch
); // we backtrack twice, with the same value
3537 is
>> q
; // read "(a,q"
3539 if (!is
.good()) goto finish
;
3541 is
>> ch
; // get the next lexeme
3543 if (!is
.good()) goto finish
;
3545 #ifdef BOOST_NO_STD_LOCALE
3548 cc
= ct
.narrow(ch
, char());
3549 #endif /* BOOST_NO_STD_LOCALE */
3551 if (cc
== ')') // read "(a,q)"
3553 o
= octonion
<T
>(p
,q
);
3557 #if BOOST_WORKAROUND(__GNUC__, < 3)
3558 is
.setstate(::std::ios::failbit
);
3560 is
.setstate(::std::ios_base::failbit
);
3561 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3564 else // read "(a,(c" or "(a,(e"
3570 if (!is
.good()) goto finish
;
3572 is
>> ch
; // get the next lexeme
3574 if (!is
.good()) goto finish
;
3576 #ifdef BOOST_NO_STD_LOCALE
3579 cc
= ct
.narrow(ch
, char());
3580 #endif /* BOOST_NO_STD_LOCALE */
3582 if (cc
== ')') // read "(a,(c)" (ambiguity resolution)
3584 is
>> ch
; // get the next lexeme
3586 if (!is
.good()) goto finish
;
3588 #ifdef BOOST_NO_STD_LOCALE
3591 cc
= ct
.narrow(ch
, char());
3592 #endif /* BOOST_NO_STD_LOCALE */
3594 if (cc
== ')') // read "(a,(c))"
3596 o
= octonion
<T
>(a
,b
,c
);
3598 else if (cc
== ',') // read "(a,(c),"
3600 u
= ::std::complex<T
>(a
);
3602 v
= ::std::complex<T
>(c
);
3604 is
>> x
; // read "(a,(c),x"
3606 if (!is
.good()) goto finish
;
3608 is
>> ch
; // get the next lexeme
3610 if (!is
.good()) goto finish
;
3612 #ifdef BOOST_NO_STD_LOCALE
3615 cc
= ct
.narrow(ch
, char());
3616 #endif /* BOOST_NO_STD_LOCALE */
3618 if (cc
== ')') // read "(a,(c),x)"
3620 o
= octonion
<T
>(u
,v
,x
);
3622 else if (cc
== ',') // read "(a,(c),x,"
3624 is
>> y
; // read "(a,(c),x,y"
3626 if (!is
.good()) goto finish
;
3628 is
>> ch
; // get the next lexeme
3630 if (!is
.good()) goto finish
;
3632 #ifdef BOOST_NO_STD_LOCALE
3635 cc
= ct
.narrow(ch
, char());
3636 #endif /* BOOST_NO_STD_LOCALE */
3638 if (cc
== ')') // read "(a,(c),x,y)"
3640 o
= octonion
<T
>(u
,v
,x
,y
);
3644 #if BOOST_WORKAROUND(__GNUC__, < 3)
3645 is
.setstate(::std::ios::failbit
);
3647 is
.setstate(::std::ios_base::failbit
);
3648 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3653 #if BOOST_WORKAROUND(__GNUC__, < 3)
3654 is
.setstate(::std::ios::failbit
);
3656 is
.setstate(::std::ios_base::failbit
);
3657 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3662 #if BOOST_WORKAROUND(__GNUC__, < 3)
3663 is
.setstate(::std::ios::failbit
);
3665 is
.setstate(::std::ios_base::failbit
);
3666 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3669 else if (cc
== ',') // read "(a,(c," or "(a,(e,"
3671 is
>> ch
; // get the next lexeme
3673 if (!is
.good()) goto finish
;
3675 #ifdef BOOST_NO_STD_LOCALE
3678 cc
= ct
.narrow(ch
, char());
3679 #endif /* BOOST_NO_STD_LOCALE */
3681 if (cc
== '(') // read "(a,(e,(" (ambiguity resolution)
3683 u
= ::std::complex<T
>(a
);
3685 x
= ::std::complex<T
>(c
); // "c" is actually "e"
3687 is
.putback(ch
); // we backtrack
3689 is
>> y
; // read "(a,(e,y"
3691 if (!is
.good()) goto finish
;
3693 is
>> ch
; // get the next lexeme
3695 if (!is
.good()) goto finish
;
3697 #ifdef BOOST_NO_STD_LOCALE
3700 cc
= ct
.narrow(ch
, char());
3701 #endif /* BOOST_NO_STD_LOCALE */
3703 if (cc
== ')') // read "(a,(e,y)"
3705 is
>> ch
; // get the next lexeme
3707 if (!is
.good()) goto finish
;
3709 #ifdef BOOST_NO_STD_LOCALE
3712 cc
= ct
.narrow(ch
, char());
3713 #endif /* BOOST_NO_STD_LOCALE */
3715 if (cc
== ')') // read "(a,(e,y))"
3717 o
= octonion
<T
>(u
,v
,x
,y
);
3721 #if BOOST_WORKAROUND(__GNUC__, < 3)
3722 is
.setstate(::std::ios::failbit
);
3724 is
.setstate(::std::ios_base::failbit
);
3725 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3730 #if BOOST_WORKAROUND(__GNUC__, < 3)
3731 is
.setstate(::std::ios::failbit
);
3733 is
.setstate(::std::ios_base::failbit
);
3734 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3737 else // read "(a,(c,d" or "(a,(e,f"
3743 if (!is
.good()) goto finish
;
3745 is
>> ch
; // get the next lexeme
3747 if (!is
.good()) goto finish
;
3749 #ifdef BOOST_NO_STD_LOCALE
3752 cc
= ct
.narrow(ch
, char());
3753 #endif /* BOOST_NO_STD_LOCALE */
3755 if (cc
== ')') // read "(a,(c,d)" (ambiguity resolution)
3757 is
>> ch
; // get the next lexeme
3759 if (!is
.good()) goto finish
;
3761 #ifdef BOOST_NO_STD_LOCALE
3764 cc
= ct
.narrow(ch
, char());
3765 #endif /* BOOST_NO_STD_LOCALE */
3767 if (cc
== ')') // read "(a,(c,d))"
3769 o
= octonion
<T
>(a
,b
,c
,d
);
3771 else if (cc
== ',') // read "(a,(c,d),"
3773 u
= ::std::complex<T
>(a
);
3775 v
= ::std::complex<T
>(c
,d
);
3777 is
>> x
; // read "(a,(c,d),x"
3779 if (!is
.good()) goto finish
;
3781 is
>> ch
; // get the next lexeme
3783 if (!is
.good()) goto finish
;
3785 #ifdef BOOST_NO_STD_LOCALE
3788 cc
= ct
.narrow(ch
, char());
3789 #endif /* BOOST_NO_STD_LOCALE */
3791 if (cc
== ')') // read "(a,(c,d),x)"
3793 o
= octonion
<T
>(u
,v
,x
);
3795 else if (cc
== ',') // read "(a,(c,d),x,"
3797 is
>> y
; // read "(a,(c,d),x,y"
3799 if (!is
.good()) goto finish
;
3801 is
>> ch
; // get the next lexeme
3803 if (!is
.good()) goto finish
;
3805 #ifdef BOOST_NO_STD_LOCALE
3808 cc
= ct
.narrow(ch
, char());
3809 #endif /* BOOST_NO_STD_LOCALE */
3811 if (cc
== ')') // read "(a,(c,d),x,y)"
3813 o
= octonion
<T
>(u
,v
,x
,y
);
3817 #if BOOST_WORKAROUND(__GNUC__, < 3)
3818 is
.setstate(::std::ios::failbit
);
3820 is
.setstate(::std::ios_base::failbit
);
3821 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3826 #if BOOST_WORKAROUND(__GNUC__, < 3)
3827 is
.setstate(::std::ios::failbit
);
3829 is
.setstate(::std::ios_base::failbit
);
3830 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3835 #if BOOST_WORKAROUND(__GNUC__, < 3)
3836 is
.setstate(::std::ios::failbit
);
3838 is
.setstate(::std::ios_base::failbit
);
3839 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3842 else if (cc
== ',') // read "(a,(e,f," (ambiguity resolution)
3844 p
= ::boost::math::quaternion
<T
>(a
);
3846 is
>> g
; // read "(a,(e,f,g"
3848 if (!is
.good()) goto finish
;
3850 is
>> ch
; // get the next lexeme
3852 if (!is
.good()) goto finish
;
3854 #ifdef BOOST_NO_STD_LOCALE
3857 cc
= ct
.narrow(ch
, char());
3858 #endif /* BOOST_NO_STD_LOCALE */
3860 if (cc
== ')') // read "(a,(e,f,g)"
3862 is
>> ch
; // get the next lexeme
3864 if (!is
.good()) goto finish
;
3866 #ifdef BOOST_NO_STD_LOCALE
3869 cc
= ct
.narrow(ch
, char());
3870 #endif /* BOOST_NO_STD_LOCALE */
3872 if (cc
== ')') // read "(a,(e,f,g))"
3874 q
= ::boost::math::quaternion
<T
>(c
,d
,g
); // "c" is actually "e" and "d" is actually "f"
3876 o
= octonion
<T
>(p
,q
);
3880 #if BOOST_WORKAROUND(__GNUC__, < 3)
3881 is
.setstate(::std::ios::failbit
);
3883 is
.setstate(::std::ios_base::failbit
);
3884 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3887 else if (cc
== ',') // read "(a,(e,f,g,"
3889 is
>> h
; // read "(a,(e,f,g,h"
3891 if (!is
.good()) goto finish
;
3893 is
>> ch
; // get the next lexeme
3895 if (!is
.good()) goto finish
;
3897 #ifdef BOOST_NO_STD_LOCALE
3900 cc
= ct
.narrow(ch
, char());
3901 #endif /* BOOST_NO_STD_LOCALE */
3903 if (cc
== ')') // read "(a,(e,f,g,h)"
3905 is
>> ch
; // get the next lexeme
3907 if (!is
.good()) goto finish
;
3909 #ifdef BOOST_NO_STD_LOCALE
3912 cc
= ct
.narrow(ch
, char());
3913 #endif /* BOOST_NO_STD_LOCALE */
3915 if (cc
== ')') // read "(a,(e,f,g,h))"
3917 q
= ::boost::math::quaternion
<T
>(c
,d
,g
,h
); // "c" is actually "e" and "d" is actually "f"
3919 o
= octonion
<T
>(p
,q
);
3923 #if BOOST_WORKAROUND(__GNUC__, < 3)
3924 is
.setstate(::std::ios::failbit
);
3926 is
.setstate(::std::ios_base::failbit
);
3927 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3932 #if BOOST_WORKAROUND(__GNUC__, < 3)
3933 is
.setstate(::std::ios::failbit
);
3935 is
.setstate(::std::ios_base::failbit
);
3936 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3941 #if BOOST_WORKAROUND(__GNUC__, < 3)
3942 is
.setstate(::std::ios::failbit
);
3944 is
.setstate(::std::ios_base::failbit
);
3945 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3950 #if BOOST_WORKAROUND(__GNUC__, < 3)
3951 is
.setstate(::std::ios::failbit
);
3953 is
.setstate(::std::ios_base::failbit
);
3954 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3960 #if BOOST_WORKAROUND(__GNUC__, < 3)
3961 is
.setstate(::std::ios::failbit
);
3963 is
.setstate(::std::ios_base::failbit
);
3964 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
3968 else // read "(a,b" or "(a,c" (ambiguity resolution)
3974 if (!is
.good()) goto finish
;
3976 is
>> ch
; // get the next lexeme
3978 if (!is
.good()) goto finish
;
3980 #ifdef BOOST_NO_STD_LOCALE
3983 cc
= ct
.narrow(ch
, char());
3984 #endif /* BOOST_NO_STD_LOCALE */
3986 if (cc
== ')') // read "(a,b)" (ambiguity resolution)
3988 o
= octonion
<T
>(a
,b
);
3990 else if (cc
== ',') // read "(a,b," or "(a,c,"
3992 is
>> ch
; // get the next lexeme
3994 if (!is
.good()) goto finish
;
3996 #ifdef BOOST_NO_STD_LOCALE
3999 cc
= ct
.narrow(ch
, char());
4000 #endif /* BOOST_NO_STD_LOCALE */
4002 if (cc
== '(') // read "(a,c,(" (ambiguity resolution)
4004 u
= ::std::complex<T
>(a
);
4006 v
= ::std::complex<T
>(b
); // "b" is actually "c"
4008 is
.putback(ch
); // we backtrack
4010 is
>> x
; // read "(a,c,x"
4012 if (!is
.good()) goto finish
;
4014 is
>> ch
; // get the next lexeme
4016 if (!is
.good()) goto finish
;
4018 #ifdef BOOST_NO_STD_LOCALE
4021 cc
= ct
.narrow(ch
, char());
4022 #endif /* BOOST_NO_STD_LOCALE */
4024 if (cc
== ')') // read "(a,c,x)"
4026 o
= octonion
<T
>(u
,v
,x
);
4028 else if (cc
== ',') // read "(a,c,x,"
4030 is
>> y
; // read "(a,c,x,y" // read "(a,c,x"
4032 if (!is
.good()) goto finish
;
4034 is
>> ch
; // get the next lexeme
4036 if (!is
.good()) goto finish
;
4038 #ifdef BOOST_NO_STD_LOCALE
4041 cc
= ct
.narrow(ch
, char());
4042 #endif /* BOOST_NO_STD_LOCALE */
4044 if (cc
== ')') // read "(a,c,x,y)"
4046 o
= octonion
<T
>(u
,v
,x
,y
);
4050 #if BOOST_WORKAROUND(__GNUC__, < 3)
4051 is
.setstate(::std::ios::failbit
);
4053 is
.setstate(::std::ios_base::failbit
);
4054 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4059 #if BOOST_WORKAROUND(__GNUC__, < 3)
4060 is
.setstate(::std::ios::failbit
);
4062 is
.setstate(::std::ios_base::failbit
);
4063 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4066 else // read "(a,b,c" or "(a,c,e"
4072 if (!is
.good()) goto finish
;
4074 is
>> ch
; // get the next lexeme
4076 if (!is
.good()) goto finish
;
4078 #ifdef BOOST_NO_STD_LOCALE
4081 cc
= ct
.narrow(ch
, char());
4082 #endif /* BOOST_NO_STD_LOCALE */
4084 if (cc
== ')') // read "(a,b,c)" (ambiguity resolution)
4086 o
= octonion
<T
>(a
,b
,c
);
4088 else if (cc
== ',') // read "(a,b,c," or "(a,c,e,"
4090 is
>> ch
; // get the next lexeme
4092 if (!is
.good()) goto finish
;
4094 #ifdef BOOST_NO_STD_LOCALE
4097 cc
= ct
.narrow(ch
, char());
4098 #endif /* BOOST_NO_STD_LOCALE */
4100 if (cc
== '(') // read "(a,c,e,(") (ambiguity resolution)
4102 u
= ::std::complex<T
>(a
);
4104 v
= ::std::complex<T
>(b
); // "b" is actually "c"
4106 x
= ::std::complex<T
>(c
); // "c" is actually "e"
4108 is
.putback(ch
); // we backtrack
4110 is
>> y
; // read "(a,c,e,y"
4112 if (!is
.good()) goto finish
;
4114 is
>> ch
; // get the next lexeme
4116 if (!is
.good()) goto finish
;
4118 #ifdef BOOST_NO_STD_LOCALE
4121 cc
= ct
.narrow(ch
, char());
4122 #endif /* BOOST_NO_STD_LOCALE */
4124 if (cc
== ')') // read "(a,c,e,y)"
4126 o
= octonion
<T
>(u
,v
,x
,y
);
4130 #if BOOST_WORKAROUND(__GNUC__, < 3)
4131 is
.setstate(::std::ios::failbit
);
4133 is
.setstate(::std::ios_base::failbit
);
4134 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4137 else // read "(a,b,c,d" (ambiguity resolution)
4139 is
.putback(ch
); // we backtrack
4143 if (!is
.good()) goto finish
;
4145 is
>> ch
; // get the next lexeme
4147 if (!is
.good()) goto finish
;
4149 #ifdef BOOST_NO_STD_LOCALE
4152 cc
= ct
.narrow(ch
, char());
4153 #endif /* BOOST_NO_STD_LOCALE */
4155 if (cc
== ')') // read "(a,b,c,d)"
4157 o
= octonion
<T
>(a
,b
,c
,d
);
4159 else if (cc
== ',') // read "(a,b,c,d,"
4161 is
>> e
; // read "(a,b,c,d,e"
4163 if (!is
.good()) goto finish
;
4165 is
>> ch
; // get the next lexeme
4167 if (!is
.good()) goto finish
;
4169 #ifdef BOOST_NO_STD_LOCALE
4172 cc
= ct
.narrow(ch
, char());
4173 #endif /* BOOST_NO_STD_LOCALE */
4175 if (cc
== ')') // read "(a,b,c,d,e)"
4177 o
= octonion
<T
>(a
,b
,c
,d
,e
);
4179 else if (cc
== ',') // read "(a,b,c,d,e,"
4181 is
>> f
; // read "(a,b,c,d,e,f"
4183 if (!is
.good()) goto finish
;
4185 is
>> ch
; // get the next lexeme
4187 if (!is
.good()) goto finish
;
4189 #ifdef BOOST_NO_STD_LOCALE
4192 cc
= ct
.narrow(ch
, char());
4193 #endif /* BOOST_NO_STD_LOCALE */
4195 if (cc
== ')') // read "(a,b,c,d,e,f)"
4197 o
= octonion
<T
>(a
,b
,c
,d
,e
,f
);
4199 else if (cc
== ',') // read "(a,b,c,d,e,f,"
4201 is
>> g
; // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f"
4203 if (!is
.good()) goto finish
;
4205 is
>> ch
; // get the next lexeme
4207 if (!is
.good()) goto finish
;
4209 #ifdef BOOST_NO_STD_LOCALE
4212 cc
= ct
.narrow(ch
, char());
4213 #endif /* BOOST_NO_STD_LOCALE */
4215 if (cc
== ')') // read "(a,b,c,d,e,f,g)"
4217 o
= octonion
<T
>(a
,b
,c
,d
,e
,f
,g
);
4219 else if (cc
== ',') // read "(a,b,c,d,e,f,g,"
4221 is
>> h
; // read "(a,b,c,d,e,f,g,h" // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f"
4223 if (!is
.good()) goto finish
;
4225 is
>> ch
; // get the next lexeme
4227 if (!is
.good()) goto finish
;
4229 #ifdef BOOST_NO_STD_LOCALE
4232 cc
= ct
.narrow(ch
, char());
4233 #endif /* BOOST_NO_STD_LOCALE */
4235 if (cc
== ')') // read "(a,b,c,d,e,f,g,h)"
4237 o
= octonion
<T
>(a
,b
,c
,d
,e
,f
,g
,h
);
4241 #if BOOST_WORKAROUND(__GNUC__, < 3)
4242 is
.setstate(::std::ios::failbit
);
4244 is
.setstate(::std::ios_base::failbit
);
4245 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4250 #if BOOST_WORKAROUND(__GNUC__, < 3)
4251 is
.setstate(::std::ios::failbit
);
4253 is
.setstate(::std::ios_base::failbit
);
4254 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4259 #if BOOST_WORKAROUND(__GNUC__, < 3)
4260 is
.setstate(::std::ios::failbit
);
4262 is
.setstate(::std::ios_base::failbit
);
4263 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4268 #if BOOST_WORKAROUND(__GNUC__, < 3)
4269 is
.setstate(::std::ios::failbit
);
4271 is
.setstate(::std::ios_base::failbit
);
4272 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4277 #if BOOST_WORKAROUND(__GNUC__, < 3)
4278 is
.setstate(::std::ios::failbit
);
4280 is
.setstate(::std::ios_base::failbit
);
4281 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4287 #if BOOST_WORKAROUND(__GNUC__, < 3)
4288 is
.setstate(::std::ios::failbit
);
4290 is
.setstate(::std::ios_base::failbit
);
4291 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4297 #if BOOST_WORKAROUND(__GNUC__, < 3)
4298 is
.setstate(::std::ios::failbit
);
4300 is
.setstate(::std::ios_base::failbit
);
4301 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4307 #if BOOST_WORKAROUND(__GNUC__, < 3)
4308 is
.setstate(::std::ios::failbit
);
4310 is
.setstate(::std::ios_base::failbit
);
4311 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4319 is
>> a
; // we extract the first component
4321 if (!is
.good()) goto finish
;
4331 #if BOOST_WORKAROUND(__GNUC__, < 3)
4332 template<typename T
>
4333 ::std::ostream
& operator << ( ::std::ostream
& os
,
4334 octonion
<T
> const & o
)
4336 template<typename T
, typename charT
, class traits
>
4337 ::std::basic_ostream
<charT
,traits
> & operator << ( ::std::basic_ostream
<charT
,traits
> & os
,
4338 octonion
<T
> const & o
)
4339 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4341 #if BOOST_WORKAROUND(__GNUC__, < 3)
4342 ::std::ostringstream s
;
4344 ::std::basic_ostringstream
<charT
,traits
> s
;
4345 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4347 s
.flags(os
.flags());
4348 #ifdef BOOST_NO_STD_LOCALE
4350 s
.imbue(os
.getloc());
4351 #endif /* BOOST_NO_STD_LOCALE */
4352 s
.precision(os
.precision());
4354 s
<< '(' << o
.R_component_1() << ','
4355 << o
.R_component_2() << ','
4356 << o
.R_component_3() << ','
4357 << o
.R_component_4() << ','
4358 << o
.R_component_5() << ','
4359 << o
.R_component_6() << ','
4360 << o
.R_component_7() << ','
4361 << o
.R_component_8() << ')';
4363 return os
<< s
.str();
4369 template<typename T
>
4370 inline T
real(octonion
<T
> const & o
)
4376 template<typename T
>
4377 inline octonion
<T
> unreal(octonion
<T
> const & o
)
4383 #define BOOST_OCTONION_VALARRAY_LOADER \
4384 using ::std::valarray; \
4386 valarray<T> temp(8); \
4388 temp[0] = o.R_component_1(); \
4389 temp[1] = o.R_component_2(); \
4390 temp[2] = o.R_component_3(); \
4391 temp[3] = o.R_component_4(); \
4392 temp[4] = o.R_component_5(); \
4393 temp[5] = o.R_component_6(); \
4394 temp[6] = o.R_component_7(); \
4395 temp[7] = o.R_component_8();
4398 template<typename T
>
4399 inline T
sup(octonion
<T
> const & o
)
4401 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
4403 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
4405 BOOST_OCTONION_VALARRAY_LOADER
4407 #if BOOST_WORKAROUND(__GNUC__, < 3)
4408 return((BOOST_GET_VALARRAY(T
, abs(temp
)).max
)());
4410 return((abs(temp
).max
)());
4411 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4415 template<typename T
>
4416 inline T
l1(octonion
<T
> const & o
)
4418 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
4420 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
4422 BOOST_OCTONION_VALARRAY_LOADER
4424 #if BOOST_WORKAROUND(__GNUC__, < 3)
4425 return(BOOST_GET_VALARRAY(T
, abs(temp
)).sum());
4427 return(abs(temp
).sum());
4428 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4432 template<typename T
>
4433 inline T
abs(const octonion
<T
> & o
)
4435 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
4437 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
4441 BOOST_OCTONION_VALARRAY_LOADER
4443 #if BOOST_WORKAROUND(__GNUC__, < 3)
4444 T maxim
= (BOOST_GET_VALARRAY(T
,abs(temp
)).max
)(); // overflow protection
4446 T maxim
= (abs(temp
).max
)(); // overflow protection
4447 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4449 if (maxim
== static_cast<T
>(0))
4455 T mixam
= static_cast<T
>(1)/maxim
; // prefer multiplications over divisions
4461 return(maxim
*sqrt(temp
.sum()));
4464 //return(::std::sqrt(norm(o)));
4468 #undef BOOST_OCTONION_VALARRAY_LOADER
4471 // Note: This is the Cayley norm, not the Euclidian norm...
4473 template<typename T
>
4474 inline T
norm(octonion
<T
> const & o
)
4476 return(real(o
*conj(o
)));
4480 template<typename T
>
4481 inline octonion
<T
> conj(octonion
<T
> const & o
)
4483 return(octonion
<T
>( +o
.R_component_1(),
4490 -o
.R_component_8()));
4494 // Note: There is little point, for the octonions, to introduce the equivalents
4495 // to the complex "arg" and the quaternionic "cylindropolar".
4498 template<typename T
>
4499 inline octonion
<T
> spherical(T
const & rho
,
4511 //T a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4512 //T b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4513 //T c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4514 //T d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4515 //T e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4516 //T f = sin(phi4)*cos(phi5)*cos(phi6);
4517 //T g = sin(phi5)*cos(phi6);
4520 T courrant
= static_cast<T
>(1);
4524 courrant
*= cos(phi6
);
4526 T g
= sin(phi5
)*courrant
;
4528 courrant
*= cos(phi5
);
4530 T f
= sin(phi4
)*courrant
;
4532 courrant
*= cos(phi4
);
4534 T e
= sin(phi3
)*courrant
;
4536 courrant
*= cos(phi3
);
4538 T d
= sin(phi2
)*courrant
;
4540 courrant
*= cos(phi2
);
4542 T c
= sin(phi1
)*courrant
;
4544 courrant
*= cos(phi1
);
4546 T b
= sin(theta
)*courrant
;
4547 T a
= cos(theta
)*courrant
;
4549 return(rho
*octonion
<T
>(a
,b
,c
,d
,e
,f
,g
,h
));
4553 template<typename T
>
4554 inline octonion
<T
> multipolar(T
const & rho1
,
4566 T a
= rho1
*cos(theta1
);
4567 T b
= rho1
*sin(theta1
);
4568 T c
= rho2
*cos(theta2
);
4569 T d
= rho2
*sin(theta2
);
4570 T e
= rho3
*cos(theta3
);
4571 T f
= rho3
*sin(theta3
);
4572 T g
= rho4
*cos(theta4
);
4573 T h
= rho4
*sin(theta4
);
4575 return(octonion
<T
>(a
,b
,c
,d
,e
,f
,g
,h
));
4579 template<typename T
>
4580 inline octonion
<T
> cylindrical(T
const & r
,
4595 return(octonion
<T
>(a
,b
,h1
,h2
,h3
,h4
,h5
,h6
));
4599 template<typename T
>
4600 inline octonion
<T
> exp(octonion
<T
> const & o
)
4605 using ::boost::math::sinc_pi
;
4609 T z
= abs(unreal(o
));
4613 return(u
*octonion
<T
>(cos(z
),
4614 w
*o
.R_component_2(), w
*o
.R_component_3(),
4615 w
*o
.R_component_4(), w
*o
.R_component_5(),
4616 w
*o
.R_component_6(), w
*o
.R_component_7(),
4617 w
*o
.R_component_8()));
4621 template<typename T
>
4622 inline octonion
<T
> cos(octonion
<T
> const & o
)
4628 using ::boost::math::sinhc_pi
;
4630 T z
= abs(unreal(o
));
4632 T w
= -sin(o
.real())*sinhc_pi(z
);
4634 return(octonion
<T
>(cos(o
.real())*cosh(z
),
4635 w
*o
.R_component_2(), w
*o
.R_component_3(),
4636 w
*o
.R_component_4(), w
*o
.R_component_5(),
4637 w
*o
.R_component_6(), w
*o
.R_component_7(),
4638 w
*o
.R_component_8()));
4642 template<typename T
>
4643 inline octonion
<T
> sin(octonion
<T
> const & o
)
4649 using ::boost::math::sinhc_pi
;
4651 T z
= abs(unreal(o
));
4653 T w
= +cos(o
.real())*sinhc_pi(z
);
4655 return(octonion
<T
>(sin(o
.real())*cosh(z
),
4656 w
*o
.R_component_2(), w
*o
.R_component_3(),
4657 w
*o
.R_component_4(), w
*o
.R_component_5(),
4658 w
*o
.R_component_6(), w
*o
.R_component_7(),
4659 w
*o
.R_component_8()));
4663 template<typename T
>
4664 inline octonion
<T
> tan(octonion
<T
> const & o
)
4666 return(sin(o
)/cos(o
));
4670 template<typename T
>
4671 inline octonion
<T
> cosh(octonion
<T
> const & o
)
4673 return((exp(+o
)+exp(-o
))/static_cast<T
>(2));
4677 template<typename T
>
4678 inline octonion
<T
> sinh(octonion
<T
> const & o
)
4680 return((exp(+o
)-exp(-o
))/static_cast<T
>(2));
4684 template<typename T
>
4685 inline octonion
<T
> tanh(octonion
<T
> const & o
)
4687 return(sinh(o
)/cosh(o
));
4691 template<typename T
>
4692 octonion
<T
> pow(octonion
<T
> const & o
,
4699 octonion
<T
> result
= pow(o
, m
);
4705 result
*= o
; // n odd
4716 return(octonion
<T
>(1));
4720 return(pow(octonion
<T
>(1)/o
,-n
));
4725 // helper templates for converting copy constructors (definition)
4730 template< typename T
,
4733 octonion
<T
> octonion_type_converter(octonion
<U
> const & rhs
)
4735 return(octonion
<T
>( static_cast<T
>(rhs
.R_component_1()),
4736 static_cast<T
>(rhs
.R_component_2()),
4737 static_cast<T
>(rhs
.R_component_3()),
4738 static_cast<T
>(rhs
.R_component_4()),
4739 static_cast<T
>(rhs
.R_component_5()),
4740 static_cast<T
>(rhs
.R_component_6()),
4741 static_cast<T
>(rhs
.R_component_7()),
4742 static_cast<T
>(rhs
.R_component_8())));
4749 #if BOOST_WORKAROUND(__GNUC__, < 3)
4750 #undef BOOST_GET_VALARRAY
4751 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */
4754 #endif /* BOOST_OCTONION_HPP */