Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:46:38

0001 //    boost octonion.hpp header file
0002 
0003 //  (C) Copyright Hubert Holin 2001.
0004 //  Distributed under the Boost Software License, Version 1.0. (See
0005 //  accompanying file LICENSE_1_0.txt or copy at
0006 //  http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 // See http://www.boost.org for updates, documentation, and revision history.
0009 
0010 
0011 #ifndef BOOST_OCTONION_HPP
0012 #define BOOST_OCTONION_HPP
0013 
0014 #include <boost/math/quaternion.hpp>
0015 #include <valarray>
0016 
0017 
0018 namespace boost
0019 {
0020     namespace math
0021     {
0022 
0023 #define    BOOST_OCTONION_ACCESSOR_GENERATOR(type)                      \
0024             type                        real() const                    \
0025             {                                                           \
0026                 return(a);                                              \
0027             }                                                           \
0028                                                                         \
0029             octonion<type>                unreal() const                \
0030             {                                                           \
0031                 return( octonion<type>(static_cast<type>(0),b,c,d,e,f,g,h));   \
0032             }                                                           \
0033                                                                         \
0034             type                            R_component_1() const       \
0035             {                                                           \
0036                 return(a);                                              \
0037             }                                                           \
0038                                                                         \
0039             type                            R_component_2() const       \
0040             {                                                           \
0041                 return(b);                                              \
0042             }                                                           \
0043                                                                         \
0044             type                            R_component_3() const       \
0045             {                                                           \
0046                 return(c);                                              \
0047             }                                                           \
0048                                                                         \
0049             type                            R_component_4() const       \
0050             {                                                           \
0051                 return(d);                                              \
0052             }                                                           \
0053                                                                         \
0054             type                            R_component_5() const       \
0055             {                                                           \
0056                 return(e);                                              \
0057             }                                                           \
0058                                                                         \
0059             type                            R_component_6() const       \
0060             {                                                           \
0061                 return(f);                                              \
0062             }                                                           \
0063                                                                         \
0064             type                            R_component_7() const       \
0065             {                                                           \
0066                 return(g);                                              \
0067             }                                                           \
0068                                                                         \
0069             type                            R_component_8() const       \
0070             {                                                           \
0071                 return(h);                                              \
0072             }                                                           \
0073                                                                         \
0074             ::std::complex<type>            C_component_1() const       \
0075             {                                                           \
0076                 return(::std::complex<type>(a,b));                      \
0077             }                                                           \
0078                                                                         \
0079             ::std::complex<type>            C_component_2() const       \
0080             {                                                           \
0081                 return(::std::complex<type>(c,d));                      \
0082             }                                                           \
0083                                                                         \
0084             ::std::complex<type>            C_component_3() const       \
0085             {                                                           \
0086                 return(::std::complex<type>(e,f));                      \
0087             }                                                           \
0088                                                                         \
0089             ::std::complex<type>            C_component_4() const       \
0090             {                                                           \
0091                 return(::std::complex<type>(g,h));                      \
0092             }                                                           \
0093                                                                         \
0094             ::boost::math::quaternion<type>    H_component_1() const    \
0095             {                                                           \
0096                 return(::boost::math::quaternion<type>(a,b,c,d));       \
0097             }                                                           \
0098                                                                         \
0099             ::boost::math::quaternion<type>    H_component_2() const    \
0100             {                                                           \
0101                 return(::boost::math::quaternion<type>(e,f,g,h));       \
0102             }
0103 
0104 
0105 #define    BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type)                                         \
0106             template<typename X>                                                                    \
0107             octonion<type> &        operator = (octonion<X> const & a_affecter)                     \
0108             {                                                                                       \
0109                 a = static_cast<type>(a_affecter.R_component_1());                                  \
0110                 b = static_cast<type>(a_affecter.R_component_2());                                  \
0111                 c = static_cast<type>(a_affecter.R_component_3());                                  \
0112                 d = static_cast<type>(a_affecter.R_component_4());                                  \
0113                 e = static_cast<type>(a_affecter.R_component_5());                                  \
0114                 f = static_cast<type>(a_affecter.R_component_6());                                  \
0115                 g = static_cast<type>(a_affecter.R_component_7());                                  \
0116                 h = static_cast<type>(a_affecter.R_component_8());                                  \
0117                                                                                                     \
0118                 return(*this);                                                                      \
0119             }                                                                                       \
0120                                                                                                     \
0121             octonion<type> &        operator = (octonion<type> const & a_affecter)                  \
0122             {                                                                                       \
0123                 a = a_affecter.a;                                                                   \
0124                 b = a_affecter.b;                                                                   \
0125                 c = a_affecter.c;                                                                   \
0126                 d = a_affecter.d;                                                                   \
0127                 e = a_affecter.e;                                                                   \
0128                 f = a_affecter.f;                                                                   \
0129                 g = a_affecter.g;                                                                   \
0130                 h = a_affecter.h;                                                                   \
0131                                                                                                     \
0132                 return(*this);                                                                      \
0133             }                                                                                       \
0134                                                                                                     \
0135             octonion<type> &        operator = (type const & a_affecter)                            \
0136             {                                                                                       \
0137                 a = a_affecter;                                                                     \
0138                                                                                                     \
0139                 b = c = d = e = f= g = h = static_cast<type>(0);                                    \
0140                                                                                                     \
0141                 return(*this);                                                                      \
0142             }                                                                                       \
0143                                                                                                     \
0144             octonion<type> &        operator = (::std::complex<type> const & a_affecter)            \
0145             {                                                                                       \
0146                 a = a_affecter.real();                                                              \
0147                 b = a_affecter.imag();                                                              \
0148                                                                                                     \
0149                 c = d = e = f = g = h = static_cast<type>(0);                                       \
0150                                                                                                     \
0151                 return(*this);                                                                      \
0152             }                                                                                       \
0153                                                                                                     \
0154             octonion<type> &        operator = (::boost::math::quaternion<type> const & a_affecter) \
0155             {                                                                                       \
0156                 a = a_affecter.R_component_1();                                                     \
0157                 b = a_affecter.R_component_2();                                                     \
0158                 c = a_affecter.R_component_3();                                                     \
0159                 d = a_affecter.R_component_4();                                                     \
0160                                                                                                     \
0161                 e = f = g = h = static_cast<type>(0);                                               \
0162                                                                                                     \
0163                 return(*this);                                                                      \
0164             }
0165 
0166 
0167 #define    BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \
0168             type    a;                                \
0169             type    b;                                \
0170             type    c;                                \
0171             type    d;                                \
0172             type    e;                                \
0173             type    f;                                \
0174             type    g;                                \
0175             type    h;                                \
0176 
0177 
0178         template<typename T>
0179         class octonion
0180         {
0181         public:
0182 
0183             using value_type = T;
0184 
0185             // constructor for O seen as R^8
0186             // (also default constructor)
0187 
0188             explicit                octonion(   T const & requested_a = T(),
0189                                                 T const & requested_b = T(),
0190                                                 T const & requested_c = T(),
0191                                                 T const & requested_d = T(),
0192                                                 T const & requested_e = T(),
0193                                                 T const & requested_f = T(),
0194                                                 T const & requested_g = T(),
0195                                                 T const & requested_h = T())
0196             :   a(requested_a),
0197                 b(requested_b),
0198                 c(requested_c),
0199                 d(requested_d),
0200                 e(requested_e),
0201                 f(requested_f),
0202                 g(requested_g),
0203                 h(requested_h)
0204             {
0205                 // nothing to do!
0206             }
0207 
0208 
0209             // constructor for H seen as C^4
0210 
0211             explicit                octonion(   ::std::complex<T> const & z0,
0212                                                 ::std::complex<T> const & z1 = ::std::complex<T>(),
0213                                                 ::std::complex<T> const & z2 = ::std::complex<T>(),
0214                                                 ::std::complex<T> const & z3 = ::std::complex<T>())
0215             :   a(z0.real()),
0216                 b(z0.imag()),
0217                 c(z1.real()),
0218                 d(z1.imag()),
0219                 e(z2.real()),
0220                 f(z2.imag()),
0221                 g(z3.real()),
0222                 h(z3.imag())
0223             {
0224                 // nothing to do!
0225             }
0226 
0227 
0228             // constructor for O seen as H^2
0229 
0230             explicit                octonion(   ::boost::math::quaternion<T> const & q0,
0231                                                 ::boost::math::quaternion<T> const & q1 = ::boost::math::quaternion<T>())
0232             :   a(q0.R_component_1()),
0233                 b(q0.R_component_2()),
0234                 c(q0.R_component_3()),
0235                 d(q0.R_component_4()),
0236                 e(q1.R_component_1()),
0237                 f(q1.R_component_2()),
0238                 g(q1.R_component_3()),
0239                 h(q1.R_component_4())
0240             {
0241                 // nothing to do!
0242             }
0243 
0244 
0245             // UNtemplated copy constructor
0246             octonion(const octonion&) = default;
0247 
0248 
0249             // templated copy constructor
0250 
0251             template<typename X>
0252             explicit                octonion(octonion<X> const & a_recopier)
0253             :   a(static_cast<T>(a_recopier.R_component_1())),
0254                 b(static_cast<T>(a_recopier.R_component_2())),
0255                 c(static_cast<T>(a_recopier.R_component_3())),
0256                 d(static_cast<T>(a_recopier.R_component_4())),
0257                 e(static_cast<T>(a_recopier.R_component_5())),
0258                 f(static_cast<T>(a_recopier.R_component_6())),
0259                 g(static_cast<T>(a_recopier.R_component_7())),
0260                 h(static_cast<T>(a_recopier.R_component_8()))
0261             {
0262                 // nothing to do!
0263             }
0264 
0265 
0266             // destructor
0267             ~octonion() = default;
0268 
0269 
0270             // accessors
0271             //
0272             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
0273             //            but unlike them there is no meaningful notion of "imaginary part".
0274             //            Instead there is an "unreal part" which itself is an octonion, and usually
0275             //            nothing simpler (as opposed to the complex number case).
0276             //            However, for practicality, there are accessors for the other components
0277             //            (these are necessary for the templated copy constructor, for instance).
0278 
0279             BOOST_OCTONION_ACCESSOR_GENERATOR(T)
0280 
0281             // assignment operators
0282 
0283             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T)
0284 
0285             // other assignment-related operators
0286             //
0287             // NOTE:    Octonion multiplication is *NOT* commutative;
0288             //            symbolically, "q *= rhs;" means "q = q * rhs;"
0289             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
0290             //            octonion multiplication is also *NOT* associative
0291 
0292             octonion<T> &            operator += (T const & rhs)
0293             {
0294                 T    at = a + rhs;    // exception guard
0295 
0296                 a = at;
0297 
0298                 return(*this);
0299             }
0300 
0301 
0302             octonion<T> &            operator += (::std::complex<T> const & rhs)
0303             {
0304                 T    at = a + rhs.real();    // exception guard
0305                 T    bt = b + rhs.imag();    // exception guard
0306 
0307                 a = at;
0308                 b = bt;
0309 
0310                 return(*this);
0311             }
0312 
0313 
0314             octonion<T> &            operator += (::boost::math::quaternion<T> const & rhs)
0315             {
0316                 T    at = a + rhs.R_component_1();    // exception guard
0317                 T    bt = b + rhs.R_component_2();    // exception guard
0318                 T    ct = c + rhs.R_component_3();    // exception guard
0319                 T    dt = d + rhs.R_component_4();    // exception guard
0320 
0321                 a = at;
0322                 b = bt;
0323                 c = ct;
0324                 d = dt;
0325 
0326                 return(*this);
0327             }
0328 
0329 
0330             template<typename X>
0331             octonion<T> &            operator += (octonion<X> const & rhs)
0332             {
0333                 T    at = a + static_cast<T>(rhs.R_component_1());    // exception guard
0334                 T    bt = b + static_cast<T>(rhs.R_component_2());    // exception guard
0335                 T    ct = c + static_cast<T>(rhs.R_component_3());    // exception guard
0336                 T    dt = d + static_cast<T>(rhs.R_component_4());    // exception guard
0337                 T    et = e + static_cast<T>(rhs.R_component_5());    // exception guard
0338                 T    ft = f + static_cast<T>(rhs.R_component_6());    // exception guard
0339                 T    gt = g + static_cast<T>(rhs.R_component_7());    // exception guard
0340                 T    ht = h + static_cast<T>(rhs.R_component_8());    // exception guard
0341 
0342                 a = at;
0343                 b = bt;
0344                 c = ct;
0345                 d = dt;
0346                 e = et;
0347                 f = ft;
0348                 g = gt;
0349                 h = ht;
0350 
0351                 return(*this);
0352             }
0353 
0354 
0355 
0356             octonion<T> &            operator -= (T const & rhs)
0357             {
0358                 T    at = a - rhs;    // exception guard
0359 
0360                 a = at;
0361 
0362                 return(*this);
0363             }
0364 
0365 
0366             octonion<T> &            operator -= (::std::complex<T> const & rhs)
0367             {
0368                 T    at = a - rhs.real();    // exception guard
0369                 T    bt = b - rhs.imag();    // exception guard
0370 
0371                 a = at;
0372                 b = bt;
0373 
0374                 return(*this);
0375             }
0376 
0377 
0378             octonion<T> &            operator -= (::boost::math::quaternion<T> const & rhs)
0379             {
0380                 T    at = a - rhs.R_component_1();    // exception guard
0381                 T    bt = b - rhs.R_component_2();    // exception guard
0382                 T    ct = c - rhs.R_component_3();    // exception guard
0383                 T    dt = d - rhs.R_component_4();    // exception guard
0384 
0385                 a = at;
0386                 b = bt;
0387                 c = ct;
0388                 d = dt;
0389 
0390                 return(*this);
0391             }
0392 
0393 
0394             template<typename X>
0395             octonion<T> &            operator -= (octonion<X> const & rhs)
0396             {
0397                 T    at = a - static_cast<T>(rhs.R_component_1());    // exception guard
0398                 T    bt = b - static_cast<T>(rhs.R_component_2());    // exception guard
0399                 T    ct = c - static_cast<T>(rhs.R_component_3());    // exception guard
0400                 T    dt = d - static_cast<T>(rhs.R_component_4());    // exception guard
0401                 T    et = e - static_cast<T>(rhs.R_component_5());    // exception guard
0402                 T    ft = f - static_cast<T>(rhs.R_component_6());    // exception guard
0403                 T    gt = g - static_cast<T>(rhs.R_component_7());    // exception guard
0404                 T    ht = h - static_cast<T>(rhs.R_component_8());    // exception guard
0405 
0406                 a = at;
0407                 b = bt;
0408                 c = ct;
0409                 d = dt;
0410                 e = et;
0411                 f = ft;
0412                 g = gt;
0413                 h = ht;
0414 
0415                 return(*this);
0416             }
0417 
0418 
0419             octonion<T> &            operator *= (T const & rhs)
0420             {
0421                 T    at = a * rhs;    // exception guard
0422                 T    bt = b * rhs;    // exception guard
0423                 T    ct = c * rhs;    // exception guard
0424                 T    dt = d * rhs;    // exception guard
0425                 T    et = e * rhs;    // exception guard
0426                 T    ft = f * rhs;    // exception guard
0427                 T    gt = g * rhs;    // exception guard
0428                 T    ht = h * rhs;    // exception guard
0429 
0430                 a = at;
0431                 b = bt;
0432                 c = ct;
0433                 d = dt;
0434                 e = et;
0435                 f = ft;
0436                 g = gt;
0437                 h = ht;
0438 
0439                 return(*this);
0440             }
0441 
0442 
0443             octonion<T> &            operator *= (::std::complex<T> const & rhs)
0444             {
0445                 T    ar = rhs.real();
0446                 T    br = rhs.imag();
0447 
0448                 T    at = +a*ar-b*br;
0449                 T    bt = +a*br+b*ar;
0450                 T    ct = +c*ar+d*br;
0451                 T    dt = -c*br+d*ar;
0452                 T    et = +e*ar+f*br;
0453                 T    ft = -e*br+f*ar;
0454                 T    gt = +g*ar-h*br;
0455                 T    ht = +g*br+h*ar;
0456 
0457                 a = at;
0458                 b = bt;
0459                 c = ct;
0460                 d = dt;
0461                 e = et;
0462                 f = ft;
0463                 g = gt;
0464                 h = ht;
0465 
0466                 return(*this);
0467             }
0468 
0469 
0470             octonion<T> &            operator *= (::boost::math::quaternion<T> const & rhs)
0471             {
0472                 T    ar = rhs.R_component_1();
0473                 T    br = rhs.R_component_2();
0474                 T    cr = rhs.R_component_2();
0475                 T    dr = rhs.R_component_2();
0476 
0477                 T    at = +a*ar-b*br-c*cr-d*dr;
0478                 T    bt = +a*br+b*ar+c*dr-d*cr;
0479                 T    ct = +a*cr-b*dr+c*ar+d*br;
0480                 T    dt = +a*dr+b*cr-c*br+d*ar;
0481                 T    et = +e*ar+f*br+g*cr+h*dr;
0482                 T    ft = -e*br+f*ar-g*dr+h*cr;
0483                 T    gt = -e*cr+f*dr+g*ar-h*br;
0484                 T    ht = -e*dr-f*cr+g*br+h*ar;
0485 
0486                 a = at;
0487                 b = bt;
0488                 c = ct;
0489                 d = dt;
0490                 e = et;
0491                 f = ft;
0492                 g = gt;
0493                 h = ht;
0494 
0495                 return(*this);
0496             }
0497 
0498 
0499             template<typename X>
0500             octonion<T> &            operator *= (octonion<X> const & rhs)
0501             {
0502                 T    ar = static_cast<T>(rhs.R_component_1());
0503                 T    br = static_cast<T>(rhs.R_component_2());
0504                 T    cr = static_cast<T>(rhs.R_component_3());
0505                 T    dr = static_cast<T>(rhs.R_component_4());
0506                 T    er = static_cast<T>(rhs.R_component_5());
0507                 T    fr = static_cast<T>(rhs.R_component_6());
0508                 T    gr = static_cast<T>(rhs.R_component_7());
0509                 T    hr = static_cast<T>(rhs.R_component_8());
0510 
0511                 T    at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr;
0512                 T    bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr;
0513                 T    ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr;
0514                 T    dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er;
0515                 T    et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr;
0516                 T    ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr;
0517                 T    gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br;
0518                 T    ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar;
0519 
0520                 a = at;
0521                 b = bt;
0522                 c = ct;
0523                 d = dt;
0524                 e = et;
0525                 f = ft;
0526                 g = gt;
0527                 h = ht;
0528 
0529                 return(*this);
0530             }
0531 
0532 
0533             octonion<T> &            operator /= (T const & rhs)
0534             {
0535                 T    at = a / rhs;    // exception guard
0536                 T    bt = b / rhs;    // exception guard
0537                 T    ct = c / rhs;    // exception guard
0538                 T    dt = d / rhs;    // exception guard
0539                 T    et = e / rhs;    // exception guard
0540                 T    ft = f / rhs;    // exception guard
0541                 T    gt = g / rhs;    // exception guard
0542                 T    ht = h / rhs;    // exception guard
0543 
0544                 a = at;
0545                 b = bt;
0546                 c = ct;
0547                 d = dt;
0548                 e = et;
0549                 f = ft;
0550                 g = gt;
0551                 h = ht;
0552 
0553                 return(*this);
0554             }
0555 
0556 
0557             octonion<T> &            operator /= (::std::complex<T> const & rhs)
0558             {
0559                 T    ar = rhs.real();
0560                 T    br = rhs.imag();
0561 
0562                 T    denominator = ar*ar+br*br;
0563 
0564                 T    at = (+a*ar-b*br)/denominator;
0565                 T    bt = (-a*br+b*ar)/denominator;
0566                 T    ct = (+c*ar-d*br)/denominator;
0567                 T    dt = (+c*br+d*ar)/denominator;
0568                 T    et = (+e*ar-f*br)/denominator;
0569                 T    ft = (+e*br+f*ar)/denominator;
0570                 T    gt = (+g*ar+h*br)/denominator;
0571                 T    ht = (+g*br+h*ar)/denominator;
0572 
0573                 a = at;
0574                 b = bt;
0575                 c = ct;
0576                 d = dt;
0577                 e = et;
0578                 f = ft;
0579                 g = gt;
0580                 h = ht;
0581 
0582                 return(*this);
0583             }
0584 
0585 
0586             octonion<T> &            operator /= (::boost::math::quaternion<T> const & rhs)
0587             {
0588                 T    ar = rhs.R_component_1();
0589                 T    br = rhs.R_component_2();
0590                 T    cr = rhs.R_component_2();
0591                 T    dr = rhs.R_component_2();
0592 
0593                 T    denominator = ar*ar+br*br+cr*cr+dr*dr;
0594 
0595                 T    at = (+a*ar+b*br+c*cr+d*dr)/denominator;
0596                 T    bt = (-a*br+b*ar-c*dr+d*cr)/denominator;
0597                 T    ct = (-a*cr+b*dr+c*ar-d*br)/denominator;
0598                 T    dt = (-a*dr-b*cr+c*br+d*ar)/denominator;
0599                 T    et = (+e*ar-f*br-g*cr-h*dr)/denominator;
0600                 T    ft = (+e*br+f*ar+g*dr-h*cr)/denominator;
0601                 T    gt = (+e*cr-f*dr+g*ar+h*br)/denominator;
0602                 T    ht = (+e*dr+f*cr-g*br+h*ar)/denominator;
0603 
0604                 a = at;
0605                 b = bt;
0606                 c = ct;
0607                 d = dt;
0608                 e = et;
0609                 f = ft;
0610                 g = gt;
0611                 h = ht;
0612 
0613                 return(*this);
0614             }
0615 
0616 
0617             template<typename X>
0618             octonion<T> &            operator /= (octonion<X> const & rhs)
0619             {
0620                 T    ar = static_cast<T>(rhs.R_component_1());
0621                 T    br = static_cast<T>(rhs.R_component_2());
0622                 T    cr = static_cast<T>(rhs.R_component_3());
0623                 T    dr = static_cast<T>(rhs.R_component_4());
0624                 T    er = static_cast<T>(rhs.R_component_5());
0625                 T    fr = static_cast<T>(rhs.R_component_6());
0626                 T    gr = static_cast<T>(rhs.R_component_7());
0627                 T    hr = static_cast<T>(rhs.R_component_8());
0628 
0629                 T    denominator = ar*ar+br*br+cr*cr+dr*dr+er*er+fr*fr+gr*gr+hr*hr;
0630 
0631                 T    at = (+a*ar+b*br+c*cr+d*dr+e*er+f*fr+g*gr+h*hr)/denominator;
0632                 T    bt = (-a*br+b*ar-c*dr+d*cr-e*fr+f*er+g*hr-h*gr)/denominator;
0633                 T    ct = (-a*cr+b*dr+c*ar-d*br-e*gr-f*hr+g*er+h*fr)/denominator;
0634                 T    dt = (-a*dr-b*cr+c*br+d*ar-e*hr+f*gr-g*fr+h*er)/denominator;
0635                 T    et = (-a*er+b*fr+c*gr+d*hr+e*ar-f*br-g*cr-h*dr)/denominator;
0636                 T    ft = (-a*fr-b*er+c*hr-d*gr+e*br+f*ar+g*dr-h*cr)/denominator;
0637                 T    gt = (-a*gr-b*hr-c*er+d*fr+e*cr-f*dr+g*ar+h*br)/denominator;
0638                 T    ht = (-a*hr+b*gr-c*fr-d*er+e*dr+f*cr-g*br+h*ar)/denominator;
0639 
0640                 a = at;
0641                 b = bt;
0642                 c = ct;
0643                 d = dt;
0644                 e = et;
0645                 f = ft;
0646                 g = gt;
0647                 h = ht;
0648 
0649                 return(*this);
0650             }
0651 
0652 
0653         protected:
0654 
0655             BOOST_OCTONION_MEMBER_DATA_GENERATOR(T)
0656 
0657 
0658         private:
0659 
0660         };
0661 
0662 
0663         // declaration of octonion specialization
0664 
0665         template<>    class octonion<float>;
0666         template<>    class octonion<double>;
0667         template<>    class octonion<long double>;
0668 
0669 
0670         // helper templates for converting copy constructors (declaration)
0671 
0672         namespace detail
0673         {
0674 
0675             template<   typename T,
0676                         typename U
0677                     >
0678             octonion<T>    octonion_type_converter(octonion<U> const & rhs);
0679         }
0680 
0681 
0682         // implementation of octonion specialization
0683 
0684 
0685 #define    BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type)                                                                               \
0686             explicit                    octonion(   type const & requested_a = static_cast<type>(0),                                \
0687                                                     type const & requested_b = static_cast<type>(0),                                \
0688                                                     type const & requested_c = static_cast<type>(0),                                \
0689                                                     type const & requested_d = static_cast<type>(0),                                \
0690                                                     type const & requested_e = static_cast<type>(0),                                \
0691                                                     type const & requested_f = static_cast<type>(0),                                \
0692                                                     type const & requested_g = static_cast<type>(0),                                \
0693                                                     type const & requested_h = static_cast<type>(0))                                \
0694             :   a(requested_a),                                                                                                     \
0695                 b(requested_b),                                                                                                     \
0696                 c(requested_c),                                                                                                     \
0697                 d(requested_d),                                                                                                     \
0698                 e(requested_e),                                                                                                     \
0699                 f(requested_f),                                                                                                     \
0700                 g(requested_g),                                                                                                     \
0701                 h(requested_h)                                                                                                      \
0702             {                                                                                                                       \
0703             }                                                                                                                       \
0704                                                                                                                                     \
0705             explicit                    octonion(   ::std::complex<type> const & z0,                                                \
0706                                                     ::std::complex<type> const & z1 = ::std::complex<type>(),                       \
0707                                                     ::std::complex<type> const & z2 = ::std::complex<type>(),                       \
0708                                                     ::std::complex<type> const & z3 = ::std::complex<type>())                       \
0709             :   a(z0.real()),                                                                                                       \
0710                 b(z0.imag()),                                                                                                       \
0711                 c(z1.real()),                                                                                                       \
0712                 d(z1.imag()),                                                                                                       \
0713                 e(z2.real()),                                                                                                       \
0714                 f(z2.imag()),                                                                                                       \
0715                 g(z3.real()),                                                                                                       \
0716                 h(z3.imag())                                                                                                        \
0717             {                                                                                                                       \
0718             }                                                                                                                       \
0719                                                                                                                                     \
0720             explicit                    octonion(   ::boost::math::quaternion<type> const & q0,                                     \
0721                                                     ::boost::math::quaternion<type> const & q1 = ::boost::math::quaternion<type>()) \
0722             :   a(q0.R_component_1()),                                                                                              \
0723                 b(q0.R_component_2()),                                                                                              \
0724                 c(q0.R_component_3()),                                                                                              \
0725                 d(q0.R_component_4()),                                                                                              \
0726                 e(q1.R_component_1()),                                                                                              \
0727                 f(q1.R_component_2()),                                                                                              \
0728                 g(q1.R_component_3()),                                                                                              \
0729                 h(q1.R_component_4())                                                                                               \
0730             {                                                                                                                       \
0731             }
0732 
0733 
0734 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type)                  \
0735             octonion<type> &            operator += (type const & rhs)  \
0736             {                                                           \
0737                 a += rhs;                                               \
0738                                                                         \
0739                 return(*this);                                          \
0740             }
0741 
0742 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type)                                  \
0743             octonion<type> &            operator += (::std::complex<type> const & rhs)  \
0744             {                                                                           \
0745                 a += rhs.real();                                                        \
0746                 b += rhs.imag();                                                        \
0747                                                                                         \
0748                 return(*this);                                                          \
0749             }
0750 
0751 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type)                                              \
0752             octonion<type> &            operator += (::boost::math::quaternion<type> const & rhs)   \
0753             {                                                                                       \
0754                 a += rhs.R_component_1();                                                           \
0755                 b += rhs.R_component_2();                                                           \
0756                 c += rhs.R_component_3();                                                           \
0757                 d += rhs.R_component_4();                                                           \
0758                                                                                                     \
0759                 return(*this);                                                                      \
0760             }
0761 
0762 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)                          \
0763             template<typename X>                                                \
0764             octonion<type> &            operator += (octonion<X> const & rhs)   \
0765             {                                                                   \
0766                 a += static_cast<type>(rhs.R_component_1());                    \
0767                 b += static_cast<type>(rhs.R_component_2());                    \
0768                 c += static_cast<type>(rhs.R_component_3());                    \
0769                 d += static_cast<type>(rhs.R_component_4());                    \
0770                 e += static_cast<type>(rhs.R_component_5());                    \
0771                 f += static_cast<type>(rhs.R_component_6());                    \
0772                 g += static_cast<type>(rhs.R_component_7());                    \
0773                 h += static_cast<type>(rhs.R_component_8());                    \
0774                                                                                 \
0775                 return(*this);                                                  \
0776             }
0777 
0778 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type)                  \
0779             octonion<type> &            operator -= (type const & rhs)  \
0780             {                                                           \
0781                 a -= rhs;                                               \
0782                                                                         \
0783                 return(*this);                                          \
0784             }
0785 
0786 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type)                                  \
0787             octonion<type> &            operator -= (::std::complex<type> const & rhs)  \
0788             {                                                                           \
0789                 a -= rhs.real();                                                        \
0790                 b -= rhs.imag();                                                        \
0791                                                                                         \
0792                 return(*this);                                                          \
0793             }
0794 
0795 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type)                                              \
0796             octonion<type> &            operator -= (::boost::math::quaternion<type> const & rhs)   \
0797             {                                                                                       \
0798                 a -= rhs.R_component_1();                                                           \
0799                 b -= rhs.R_component_2();                                                           \
0800                 c -= rhs.R_component_3();                                                           \
0801                 d -= rhs.R_component_4();                                                           \
0802                                                                                                     \
0803                 return(*this);                                                                      \
0804             }
0805 
0806 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)                        \
0807             template<typename X>                                              \
0808             octonion<type> &            operator -= (octonion<X> const & rhs) \
0809             {                                                                 \
0810                 a -= static_cast<type>(rhs.R_component_1());                  \
0811                 b -= static_cast<type>(rhs.R_component_2());                  \
0812                 c -= static_cast<type>(rhs.R_component_3());                  \
0813                 d -= static_cast<type>(rhs.R_component_4());                  \
0814                 e -= static_cast<type>(rhs.R_component_5());                  \
0815                 f -= static_cast<type>(rhs.R_component_6());                  \
0816                 g -= static_cast<type>(rhs.R_component_7());                  \
0817                 h -= static_cast<type>(rhs.R_component_8());                  \
0818                                                                               \
0819                 return(*this);                                                \
0820             }
0821 
0822 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type)                   \
0823             octonion<type> &            operator *= (type const & rhs)   \
0824             {                                                            \
0825                 a *= rhs;                                                \
0826                 b *= rhs;                                                \
0827                 c *= rhs;                                                \
0828                 d *= rhs;                                                \
0829                 e *= rhs;                                                \
0830                 f *= rhs;                                                \
0831                 g *= rhs;                                                \
0832                 h *= rhs;                                                \
0833                                                                          \
0834                 return(*this);                                           \
0835             }
0836 
0837 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type)                                  \
0838             octonion<type> &            operator *= (::std::complex<type> const & rhs)  \
0839             {                                                                           \
0840                 type    ar = rhs.real();                                                \
0841                 type    br = rhs.imag();                                                \
0842                                                                                         \
0843                 type    at = +a*ar-b*br;                                                \
0844                 type    bt = +a*br+b*ar;                                                \
0845                 type    ct = +c*ar+d*br;                                                \
0846                 type    dt = -c*br+d*ar;                                                \
0847                 type    et = +e*ar+f*br;                                                \
0848                 type    ft = -e*br+f*ar;                                                \
0849                 type    gt = +g*ar-h*br;                                                \
0850                 type    ht = +g*br+h*ar;                                                \
0851                                                                                         \
0852                 a = at;                                                                 \
0853                 b = bt;                                                                 \
0854                 c = ct;                                                                 \
0855                 d = dt;                                                                 \
0856                 e = et;                                                                 \
0857                 f = ft;                                                                 \
0858                 g = gt;                                                                 \
0859                 h = ht;                                                                 \
0860                                                                                         \
0861                 return(*this);                                                          \
0862             }
0863 
0864 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type)                                                    \
0865             octonion<type> &            operator *= (::boost::math::quaternion<type> const & rhs)   \
0866             {                                                                                       \
0867                 type    ar = rhs.R_component_1();                                                   \
0868                 type    br = rhs.R_component_2();                                                   \
0869                 type    cr = rhs.R_component_2();                                                   \
0870                 type    dr = rhs.R_component_2();                                                   \
0871                                                                                                     \
0872                 type    at = +a*ar-b*br-c*cr-d*dr;                                                  \
0873                 type    bt = +a*br+b*ar+c*dr-d*cr;                                                  \
0874                 type    ct = +a*cr-b*dr+c*ar+d*br;                                                  \
0875                 type    dt = +a*dr+b*cr-c*br+d*ar;                                                  \
0876                 type    et = +e*ar+f*br+g*cr+h*dr;                                                  \
0877                 type    ft = -e*br+f*ar-g*dr+h*cr;                                                  \
0878                 type    gt = -e*cr+f*dr+g*ar-h*br;                                                  \
0879                 type    ht = -e*dr-f*cr+g*br+h*ar;                                                  \
0880                                                                                                     \
0881                 a = at;                                                                             \
0882                 b = bt;                                                                             \
0883                 c = ct;                                                                             \
0884                 d = dt;                                                                             \
0885                 e = et;                                                                             \
0886                 f = ft;                                                                             \
0887                 g = gt;                                                                             \
0888                 h = ht;                                                                             \
0889                                                                                                     \
0890                 return(*this);                                                                      \
0891             }
0892 
0893 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)                          \
0894             template<typename X>                                                \
0895             octonion<type> &            operator *= (octonion<X> const & rhs)   \
0896             {                                                                   \
0897                 type    ar = static_cast<type>(rhs.R_component_1());            \
0898                 type    br = static_cast<type>(rhs.R_component_2());            \
0899                 type    cr = static_cast<type>(rhs.R_component_3());            \
0900                 type    dr = static_cast<type>(rhs.R_component_4());            \
0901                 type    er = static_cast<type>(rhs.R_component_5());            \
0902                 type    fr = static_cast<type>(rhs.R_component_6());            \
0903                 type    gr = static_cast<type>(rhs.R_component_7());            \
0904                 type    hr = static_cast<type>(rhs.R_component_8());            \
0905                                                                                 \
0906                 type    at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr;          \
0907                 type    bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr;          \
0908                 type    ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr;          \
0909                 type    dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er;          \
0910                 type    et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr;          \
0911                 type    ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr;          \
0912                 type    gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br;          \
0913                 type    ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar;          \
0914                                                                                 \
0915                 a = at;                                                         \
0916                 b = bt;                                                         \
0917                 c = ct;                                                         \
0918                 d = dt;                                                         \
0919                 e = et;                                                         \
0920                 f = ft;                                                         \
0921                 g = gt;                                                         \
0922                 h = ht;                                                         \
0923                                                                                 \
0924                 return(*this);                                                  \
0925             }
0926 
0927 // There is quite a lot of repetition in the code below. This is intentional.
0928 // The last conditional block is the normal form, and the others merely
0929 // consist of workarounds for various compiler deficiencies. Hopefully, when
0930 // more compilers are conformant and we can retire support for those that are
0931 // not, we will be able to remove the clutter. This is makes the situation
0932 // (painfully) explicit.
0933 
0934 #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type)                  \
0935             octonion<type> &            operator /= (type const & rhs)  \
0936             {                                                           \
0937                 a /= rhs;                                               \
0938                 b /= rhs;                                               \
0939                 c /= rhs;                                               \
0940                 d /= rhs;                                               \
0941                                                                         \
0942                 return(*this);                                          \
0943             }
0944 
0945 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
0946     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                              \
0947             octonion<type> &            operator /= (::std::complex<type> const & rhs)  \
0948             {                                                                           \
0949                 using    ::std::valarray;                                               \
0950                 using    ::std::abs;                                                    \
0951                                                                                         \
0952                 valarray<type>    tr(2);                                                \
0953                                                                                         \
0954                 tr[0] = rhs.real();                                                     \
0955                 tr[1] = rhs.imag();                                                     \
0956                                                                                         \
0957                 type            mixam = static_cast<type>(1)/(abs(tr).max)();           \
0958                                                                                         \
0959                 tr *= mixam;                                                            \
0960                                                                                         \
0961                 valarray<type>    tt(8);                                                \
0962                                                                                         \
0963                 tt[0] = +a*tr[0]-b*tr[1];                                               \
0964                 tt[1] = -a*tr[1]+b*tr[0];                                               \
0965                 tt[2] = +c*tr[0]-d*tr[1];                                               \
0966                 tt[3] = +c*tr[1]+d*tr[0];                                               \
0967                 tt[4] = +e*tr[0]-f*tr[1];                                               \
0968                 tt[5] = +e*tr[1]+f*tr[0];                                               \
0969                 tt[6] = +g*tr[0]+h*tr[1];                                               \
0970                 tt[7] = +g*tr[1]+h*tr[0];                                               \
0971                                                                                         \
0972                 tr *= tr;                                                               \
0973                                                                                         \
0974                 tt *= (mixam/tr.sum());                                                 \
0975                                                                                         \
0976                 a = tt[0];                                                              \
0977                 b = tt[1];                                                              \
0978                 c = tt[2];                                                              \
0979                 d = tt[3];                                                              \
0980                 e = tt[4];                                                              \
0981                 f = tt[5];                                                              \
0982                 g = tt[6];                                                              \
0983                 h = tt[7];                                                              \
0984                                                                                         \
0985                 return(*this);                                                          \
0986             }
0987 #else
0988     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)                              \
0989             octonion<type> &            operator /= (::std::complex<type> const & rhs)  \
0990             {                                                                           \
0991                 using    ::std::valarray;                                               \
0992                                                                                         \
0993                 valarray<type>    tr(2);                                                \
0994                                                                                         \
0995                 tr[0] = rhs.real();                                                     \
0996                 tr[1] = rhs.imag();                                                     \
0997                                                                                         \
0998                 type            mixam = static_cast<type>(1)/(abs(tr).max)();           \
0999                                                                                         \
1000                 tr *= mixam;                                                            \
1001                                                                                         \
1002                 valarray<type>    tt(8);                                                \
1003                                                                                         \
1004                 tt[0] = +a*tr[0]-b*tr[1];                                               \
1005                 tt[1] = -a*tr[1]+b*tr[0];                                               \
1006                 tt[2] = +c*tr[0]-d*tr[1];                                               \
1007                 tt[3] = +c*tr[1]+d*tr[0];                                               \
1008                 tt[4] = +e*tr[0]-f*tr[1];                                               \
1009                 tt[5] = +e*tr[1]+f*tr[0];                                               \
1010                 tt[6] = +g*tr[0]+h*tr[1];                                               \
1011                 tt[7] = +g*tr[1]+h*tr[0];                                               \
1012                                                                                         \
1013                 tr *= tr;                                                               \
1014                                                                                         \
1015                 tt *= (mixam/tr.sum());                                                 \
1016                                                                                         \
1017                 a = tt[0];                                                              \
1018                 b = tt[1];                                                              \
1019                 c = tt[2];                                                              \
1020                 d = tt[3];                                                              \
1021                 e = tt[4];                                                              \
1022                 f = tt[5];                                                              \
1023                 g = tt[6];                                                              \
1024                 h = tt[7];                                                              \
1025                                                                                         \
1026                 return(*this);                                                          \
1027             }
1028 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
1029 
1030 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1031     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \
1032             octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \
1033             {                                                                                        \
1034                 using    ::std::valarray;                                                            \
1035                 using    ::std::abs;                                                                 \
1036                                                                                                      \
1037                 valarray<type>    tr(4);                                                             \
1038                                                                                                      \
1039                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
1040                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
1041                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
1042                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
1043                                                                                                      \
1044                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
1045                                                                                                      \
1046                 tr *= mixam;                                                                         \
1047                                                                                                      \
1048                 valarray<type>    tt(8);                                                             \
1049                                                                                                      \
1050                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \
1051                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \
1052                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \
1053                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \
1054                 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \
1055                 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \
1056                 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \
1057                 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \
1058                                                                                                      \
1059                 tr *= tr;                                                                            \
1060                                                                                                      \
1061                 tt *= (mixam/tr.sum());                                                              \
1062                                                                                                      \
1063                 a = tt[0];                                                                           \
1064                 b = tt[1];                                                                           \
1065                 c = tt[2];                                                                           \
1066                 d = tt[3];                                                                           \
1067                 e = tt[4];                                                                           \
1068                 f = tt[5];                                                                           \
1069                 g = tt[6];                                                                           \
1070                 h = tt[7];                                                                           \
1071                                                                                                      \
1072                 return(*this);                                                                       \
1073             }
1074 #else
1075     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)                                           \
1076             octonion<type> &            operator /= (::boost::math::quaternion<type> const & rhs)    \
1077             {                                                                                        \
1078                 using    ::std::valarray;                                                            \
1079                                                                                                      \
1080                 valarray<type>    tr(4);                                                             \
1081                                                                                                      \
1082                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
1083                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
1084                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
1085                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
1086                                                                                                      \
1087                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
1088                                                                                                      \
1089                 tr *= mixam;                                                                         \
1090                                                                                                      \
1091                 valarray<type>    tt(8);                                                             \
1092                                                                                                      \
1093                 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3];                                            \
1094                 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2];                                            \
1095                 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1];                                            \
1096                 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0];                                            \
1097                 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3];                                            \
1098                 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2];                                            \
1099                 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1];                                            \
1100                 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0];                                            \
1101                                                                                                      \
1102                 tr *= tr;                                                                            \
1103                                                                                                      \
1104                 tt *= (mixam/tr.sum());                                                              \
1105                                                                                                      \
1106                 a = tt[0];                                                                           \
1107                 b = tt[1];                                                                           \
1108                 c = tt[2];                                                                           \
1109                 d = tt[3];                                                                           \
1110                 e = tt[4];                                                                           \
1111                 f = tt[5];                                                                           \
1112                 g = tt[6];                                                                           \
1113                 h = tt[7];                                                                           \
1114                                                                                                      \
1115                 return(*this);                                                                       \
1116             }
1117 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
1118 
1119 #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
1120     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \
1121             template<typename X>                                                                     \
1122             octonion<type> &            operator /= (octonion<X> const & rhs)                        \
1123             {                                                                                        \
1124                 using    ::std::valarray;                                                            \
1125                 using    ::std::abs;                                                                 \
1126                                                                                                      \
1127                 valarray<type>    tr(8);                                                             \
1128                                                                                                      \
1129                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
1130                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
1131                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
1132                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
1133                 tr[4] = static_cast<type>(rhs.R_component_5());                                      \
1134                 tr[5] = static_cast<type>(rhs.R_component_6());                                      \
1135                 tr[6] = static_cast<type>(rhs.R_component_7());                                      \
1136                 tr[7] = static_cast<type>(rhs.R_component_8());                                      \
1137                                                                                                      \
1138                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
1139                                                                                                      \
1140                 tr *= mixam;                                                                         \
1141                                                                                                      \
1142                 valarray<type>    tt(8);                                                             \
1143                                                                                                      \
1144                 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];            \
1145                 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];            \
1146                 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];            \
1147                 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];            \
1148                 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];            \
1149                 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];            \
1150                 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];            \
1151                 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];            \
1152                                                                                                      \
1153                 tr *= tr;                                                                            \
1154                                                                                                      \
1155                 tt *= (mixam/tr.sum());                                                              \
1156                                                                                                      \
1157                 a = tt[0];                                                                           \
1158                 b = tt[1];                                                                           \
1159                 c = tt[2];                                                                           \
1160                 d = tt[3];                                                                           \
1161                 e = tt[4];                                                                           \
1162                 f = tt[5];                                                                           \
1163                 g = tt[6];                                                                           \
1164                 h = tt[7];                                                                           \
1165                                                                                                      \
1166                 return(*this);                                                                       \
1167             }
1168 #else
1169     #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)                                           \
1170             template<typename X>                                                                     \
1171             octonion<type> &            operator /= (octonion<X> const & rhs)                        \
1172             {                                                                                        \
1173                 using    ::std::valarray;                                                            \
1174                                                                                                      \
1175                 valarray<type>    tr(8);                                                             \
1176                                                                                                      \
1177                 tr[0] = static_cast<type>(rhs.R_component_1());                                      \
1178                 tr[1] = static_cast<type>(rhs.R_component_2());                                      \
1179                 tr[2] = static_cast<type>(rhs.R_component_3());                                      \
1180                 tr[3] = static_cast<type>(rhs.R_component_4());                                      \
1181                 tr[4] = static_cast<type>(rhs.R_component_5());                                      \
1182                 tr[5] = static_cast<type>(rhs.R_component_6());                                      \
1183                 tr[6] = static_cast<type>(rhs.R_component_7());                                      \
1184                 tr[7] = static_cast<type>(rhs.R_component_8());                                      \
1185                                                                                                      \
1186                 type            mixam = static_cast<type>(1)/(abs(tr).max)();                        \
1187                                                                                                      \
1188                 tr *= mixam;                                                                         \
1189                                                                                                      \
1190                 valarray<type>    tt(8);                                                             \
1191                                                                                                      \
1192                 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];            \
1193                 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];            \
1194                 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];            \
1195                 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];            \
1196                 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];            \
1197                 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];            \
1198                 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];            \
1199                 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];            \
1200                                                                                                      \
1201                 tr *= tr;                                                                            \
1202                                                                                                      \
1203                 tt *= (mixam/tr.sum());                                                              \
1204                                                                                                      \
1205                 a = tt[0];                                                                           \
1206                 b = tt[1];                                                                           \
1207                 c = tt[2];                                                                           \
1208                 d = tt[3];                                                                           \
1209                 e = tt[4];                                                                           \
1210                 f = tt[5];                                                                           \
1211                 g = tt[6];                                                                           \
1212                 h = tt[7];                                                                           \
1213                                                                                                      \
1214                 return(*this);                                                                       \
1215             }
1216 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
1217 
1218 
1219 #define    BOOST_OCTONION_MEMBER_ADD_GENERATOR(type)       \
1220         BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type)        \
1221         BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type)        \
1222         BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type)        \
1223         BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type)
1224 
1225 #define    BOOST_OCTONION_MEMBER_SUB_GENERATOR(type)       \
1226         BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type)        \
1227         BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type)        \
1228         BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type)        \
1229         BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type)
1230 
1231 #define    BOOST_OCTONION_MEMBER_MUL_GENERATOR(type)       \
1232         BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type)        \
1233         BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type)        \
1234         BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type)        \
1235         BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type)
1236 
1237 #define    BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)       \
1238         BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type)        \
1239         BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type)        \
1240         BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type)        \
1241         BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type)
1242 
1243 #define    BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \
1244         BOOST_OCTONION_MEMBER_ADD_GENERATOR(type)          \
1245         BOOST_OCTONION_MEMBER_SUB_GENERATOR(type)          \
1246         BOOST_OCTONION_MEMBER_MUL_GENERATOR(type)          \
1247         BOOST_OCTONION_MEMBER_DIV_GENERATOR(type)
1248 
1249 
1250         template<>
1251         class octonion<float>
1252         {
1253         public:
1254 
1255             using value_type = float;
1256 
1257             BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float)
1258 
1259             // UNtemplated copy constructor
1260             octonion(const octonion&) = default;
1261 
1262             // explicit copy constructors (precision-losing converters)
1263 
1264             explicit                    octonion(octonion<double> const & a_recopier)
1265             {
1266                 *this = detail::octonion_type_converter<float, double>(a_recopier);
1267             }
1268 
1269             explicit                    octonion(octonion<long double> const & a_recopier)
1270             {
1271                 *this = detail::octonion_type_converter<float, long double>(a_recopier);
1272             }
1273 
1274             // destructor
1275             ~octonion() = default;
1276 
1277             // accessors
1278             //
1279             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
1280             //            but unlike them there is no meaningful notion of "imaginary part".
1281             //            Instead there is an "unreal part" which itself is an octonion, and usually
1282             //            nothing simpler (as opposed to the complex number case).
1283             //            However, for practicality, there are accessors for the other components
1284             //            (these are necessary for the templated copy constructor, for instance).
1285 
1286             BOOST_OCTONION_ACCESSOR_GENERATOR(float)
1287 
1288             // assignment operators
1289 
1290             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float)
1291 
1292             // other assignment-related operators
1293             //
1294             // NOTE:    Octonion multiplication is *NOT* commutative;
1295             //            symbolically, "q *= rhs;" means "q = q * rhs;"
1296             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
1297             //            octonion multiplication is also *NOT* associative
1298 
1299             BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float)
1300 
1301 
1302         protected:
1303 
1304             BOOST_OCTONION_MEMBER_DATA_GENERATOR(float)
1305         };
1306 
1307 
1308         template<>
1309         class octonion<double>
1310         {
1311         public:
1312 
1313             using value_type = double;
1314 
1315             BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double)
1316 
1317             // Untemplated copy constructor
1318             octonion(const octonion&) = default;
1319 
1320             // converting copy constructor
1321 
1322             explicit                    octonion(octonion<float> const & a_recopier)
1323             {
1324                 *this = detail::octonion_type_converter<double, float>(a_recopier);
1325             }
1326 
1327             // explicit copy constructors (precision-losing converters)
1328 
1329             explicit                    octonion(octonion<long double> const & a_recopier)
1330             {
1331                 *this = detail::octonion_type_converter<double, long double>(a_recopier);
1332             }
1333 
1334             // destructor
1335             // (this is taken care of by the compiler itself)
1336 
1337             // accessors
1338             //
1339             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
1340             //            but unlike them there is no meaningful notion of "imaginary part".
1341             //            Instead there is an "unreal part" which itself is an octonion, and usually
1342             //            nothing simpler (as opposed to the complex number case).
1343             //            However, for practicality, there are accessors for the other components
1344             //            (these are necessary for the templated copy constructor, for instance).
1345 
1346             BOOST_OCTONION_ACCESSOR_GENERATOR(double)
1347 
1348             // assignment operators
1349 
1350             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double)
1351 
1352             // other assignment-related operators
1353             //
1354             // NOTE:    Octonion multiplication is *NOT* commutative;
1355             //            symbolically, "q *= rhs;" means "q = q * rhs;"
1356             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
1357             //            octonion multiplication is also *NOT* associative
1358 
1359             BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double)
1360 
1361 
1362         protected:
1363 
1364             BOOST_OCTONION_MEMBER_DATA_GENERATOR(double)
1365         };
1366 
1367 
1368         template<>
1369         class octonion<long double>
1370         {
1371         public:
1372 
1373             using value_type = long double;
1374 
1375             BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double)
1376 
1377             // UNtemplated copy constructor
1378             octonion(const octonion&) = default;
1379 
1380             // converting copy constructor
1381 
1382             explicit                            octonion(octonion<float> const & a_recopier)
1383             {
1384                 *this = detail::octonion_type_converter<long double, float>(a_recopier);
1385             }
1386 
1387 
1388             explicit                            octonion(octonion<double> const & a_recopier)
1389             {
1390                 *this = detail::octonion_type_converter<long double, double>(a_recopier);
1391             }
1392 
1393 
1394             // destructor
1395             // (this is taken care of by the compiler itself)
1396 
1397             // accessors
1398             //
1399             // Note:    Like complex number, octonions do have a meaningful notion of "real part",
1400             //            but unlike them there is no meaningful notion of "imaginary part".
1401             //            Instead there is an "unreal part" which itself is an octonion, and usually
1402             //            nothing simpler (as opposed to the complex number case).
1403             //            However, for practicality, there are accessors for the other components
1404             //            (these are necessary for the templated copy constructor, for instance).
1405 
1406             BOOST_OCTONION_ACCESSOR_GENERATOR(long double)
1407 
1408             // assignment operators
1409 
1410             BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double)
1411 
1412             // other assignment-related operators
1413             //
1414             // NOTE:    Octonion multiplication is *NOT* commutative;
1415             //            symbolically, "q *= rhs;" means "q = q * rhs;"
1416             //            and "q /= rhs;" means "q = q * inverse_of(rhs);";
1417             //            octonion multiplication is also *NOT* associative
1418 
1419             BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double)
1420 
1421 
1422         protected:
1423 
1424             BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double)
1425 
1426 
1427         private:
1428 
1429         };
1430 
1431 
1432 #undef    BOOST_OCTONION_CONSTRUCTOR_GENERATOR
1433 
1434 #undef    BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR
1435 
1436 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR
1437 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR
1438 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR
1439 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR
1440 
1441 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_1
1442 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_2
1443 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_3
1444 #undef    BOOST_OCTONION_MEMBER_ADD_GENERATOR_4
1445 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_1
1446 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_2
1447 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_3
1448 #undef    BOOST_OCTONION_MEMBER_SUB_GENERATOR_4
1449 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_1
1450 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_2
1451 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_3
1452 #undef    BOOST_OCTONION_MEMBER_MUL_GENERATOR_4
1453 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_1
1454 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_2
1455 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_3
1456 #undef    BOOST_OCTONION_MEMBER_DIV_GENERATOR_4
1457 
1458 
1459 #undef    BOOST_OCTONION_MEMBER_DATA_GENERATOR
1460 
1461 #undef    BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR
1462 
1463 #undef    BOOST_OCTONION_ACCESSOR_GENERATOR
1464 
1465 
1466         // operators
1467 
1468 #define    BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \
1469         {                                             \
1470             octonion<T>    res(lhs);                  \
1471             res op##= rhs;                            \
1472             return(res);                              \
1473         }
1474 
1475 #define    BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op)                                                                              \
1476         template<typename T>                                                                                                      \
1477         inline octonion<T>                        operator op (T const & lhs, octonion<T> const & rhs)                            \
1478         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1479 
1480 #define    BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op)                                                                              \
1481         template<typename T>                                                                                                      \
1482         inline octonion<T>                        operator op (octonion<T> const & lhs, T const & rhs)                            \
1483         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1484 
1485 #define    BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op)                                                                              \
1486         template<typename T>                                                                                                      \
1487         inline octonion<T>                        operator op (::std::complex<T> const & lhs, octonion<T> const & rhs)            \
1488         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1489 
1490 #define    BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op)                                                                              \
1491         template<typename T>                                                                                                      \
1492         inline octonion<T>                        operator op (octonion<T> const & lhs, ::std::complex<T> const & rhs)            \
1493         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1494 
1495 #define    BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op)                                                                              \
1496         template<typename T>                                                                                                      \
1497         inline octonion<T>                        operator op (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) \
1498         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1499 
1500 #define    BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op)                                                                              \
1501         template<typename T>                                                                                                      \
1502         inline octonion<T>                        operator op (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) \
1503         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1504 
1505 #define    BOOST_OCTONION_OPERATOR_GENERATOR_4(op)                                                                                \
1506         template<typename T>                                                                                                      \
1507         inline octonion<T>                        operator op (octonion<T> const & lhs, octonion<T> const & rhs)                  \
1508         BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op)
1509 
1510 #define    BOOST_OCTONION_OPERATOR_GENERATOR(op)     \
1511         BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op)    \
1512         BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op)    \
1513         BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op)    \
1514         BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op)    \
1515         BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op)    \
1516         BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op)    \
1517         BOOST_OCTONION_OPERATOR_GENERATOR_4(op)
1518 
1519 
1520         BOOST_OCTONION_OPERATOR_GENERATOR(+)
1521         BOOST_OCTONION_OPERATOR_GENERATOR(-)
1522         BOOST_OCTONION_OPERATOR_GENERATOR(*)
1523         BOOST_OCTONION_OPERATOR_GENERATOR(/)
1524 
1525 
1526 #undef    BOOST_OCTONION_OPERATOR_GENERATOR
1527 
1528 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_1_L
1529 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_1_R
1530 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_2_L
1531 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_2_R
1532 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_3_L
1533 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_3_R
1534 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_4
1535 
1536 #undef    BOOST_OCTONION_OPERATOR_GENERATOR_BODY
1537 
1538 
1539         template<typename T>
1540         inline octonion<T>                        operator + (octonion<T> const & o)
1541         {
1542             return(o);
1543         }
1544 
1545 
1546         template<typename T>
1547         inline octonion<T>                        operator - (octonion<T> const & o)
1548         {
1549             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()));
1550         }
1551 
1552 
1553         template<typename T>
1554         inline bool                                operator == (T const & lhs, octonion<T> const & rhs)
1555         {
1556             return(
1557                         (rhs.R_component_1() == lhs)&&
1558                         (rhs.R_component_2() == static_cast<T>(0))&&
1559                         (rhs.R_component_3() == static_cast<T>(0))&&
1560                         (rhs.R_component_4() == static_cast<T>(0))&&
1561                         (rhs.R_component_5() == static_cast<T>(0))&&
1562                         (rhs.R_component_6() == static_cast<T>(0))&&
1563                         (rhs.R_component_7() == static_cast<T>(0))&&
1564                         (rhs.R_component_8() == static_cast<T>(0))
1565                     );
1566         }
1567 
1568 
1569         template<typename T>
1570         inline bool                                operator == (octonion<T> const & lhs, T const & rhs)
1571         {
1572             return(
1573                         (lhs.R_component_1() == rhs)&&
1574                         (lhs.R_component_2() == static_cast<T>(0))&&
1575                         (lhs.R_component_3() == static_cast<T>(0))&&
1576                         (lhs.R_component_4() == static_cast<T>(0))&&
1577                         (lhs.R_component_5() == static_cast<T>(0))&&
1578                         (lhs.R_component_6() == static_cast<T>(0))&&
1579                         (lhs.R_component_7() == static_cast<T>(0))&&
1580                         (lhs.R_component_8() == static_cast<T>(0))
1581                     );
1582         }
1583 
1584 
1585         template<typename T>
1586         inline bool                                operator == (::std::complex<T> const & lhs, octonion<T> const & rhs)
1587         {
1588             return(
1589                         (rhs.R_component_1() == lhs.real())&&
1590                         (rhs.R_component_2() == lhs.imag())&&
1591                         (rhs.R_component_3() == static_cast<T>(0))&&
1592                         (rhs.R_component_4() == static_cast<T>(0))&&
1593                         (rhs.R_component_5() == static_cast<T>(0))&&
1594                         (rhs.R_component_6() == static_cast<T>(0))&&
1595                         (rhs.R_component_7() == static_cast<T>(0))&&
1596                         (rhs.R_component_8() == static_cast<T>(0))
1597                     );
1598         }
1599 
1600 
1601         template<typename T>
1602         inline bool                                operator == (octonion<T> const & lhs, ::std::complex<T> const & rhs)
1603         {
1604             return(
1605                         (lhs.R_component_1() == rhs.real())&&
1606                         (lhs.R_component_2() == rhs.imag())&&
1607                         (lhs.R_component_3() == static_cast<T>(0))&&
1608                         (lhs.R_component_4() == static_cast<T>(0))&&
1609                         (lhs.R_component_5() == static_cast<T>(0))&&
1610                         (lhs.R_component_6() == static_cast<T>(0))&&
1611                         (lhs.R_component_7() == static_cast<T>(0))&&
1612                         (lhs.R_component_8() == static_cast<T>(0))
1613                     );
1614         }
1615 
1616 
1617         template<typename T>
1618         inline bool                                operator == (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs)
1619         {
1620             return(
1621                         (rhs.R_component_1() == lhs.R_component_1())&&
1622                         (rhs.R_component_2() == lhs.R_component_2())&&
1623                         (rhs.R_component_3() == lhs.R_component_3())&&
1624                         (rhs.R_component_4() == lhs.R_component_4())&&
1625                         (rhs.R_component_5() == static_cast<T>(0))&&
1626                         (rhs.R_component_6() == static_cast<T>(0))&&
1627                         (rhs.R_component_7() == static_cast<T>(0))&&
1628                         (rhs.R_component_8() == static_cast<T>(0))
1629                     );
1630         }
1631 
1632 
1633         template<typename T>
1634         inline bool                                operator == (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs)
1635         {
1636             return(
1637                         (lhs.R_component_1() == rhs.R_component_1())&&
1638                         (lhs.R_component_2() == rhs.R_component_2())&&
1639                         (lhs.R_component_3() == rhs.R_component_3())&&
1640                         (lhs.R_component_4() == rhs.R_component_4())&&
1641                         (lhs.R_component_5() == static_cast<T>(0))&&
1642                         (lhs.R_component_6() == static_cast<T>(0))&&
1643                         (lhs.R_component_7() == static_cast<T>(0))&&
1644                         (lhs.R_component_8() == static_cast<T>(0))
1645                     );
1646         }
1647 
1648 
1649         template<typename T>
1650         inline bool                                operator == (octonion<T> const & lhs, octonion<T> const & rhs)
1651         {
1652             return(
1653                         (rhs.R_component_1() == lhs.R_component_1())&&
1654                         (rhs.R_component_2() == lhs.R_component_2())&&
1655                         (rhs.R_component_3() == lhs.R_component_3())&&
1656                         (rhs.R_component_4() == lhs.R_component_4())&&
1657                         (rhs.R_component_5() == lhs.R_component_5())&&
1658                         (rhs.R_component_6() == lhs.R_component_6())&&
1659                         (rhs.R_component_7() == lhs.R_component_7())&&
1660                         (rhs.R_component_8() == lhs.R_component_8())
1661                     );
1662         }
1663 
1664 
1665 #define    BOOST_OCTONION_NOT_EQUAL_GENERATOR \
1666         {                                     \
1667             return(!(lhs == rhs));            \
1668         }
1669 
1670         template<typename T>
1671         inline bool                                operator != (T const & lhs, octonion<T> const & rhs)
1672         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1673 
1674         template<typename T>
1675         inline bool                                operator != (octonion<T> const & lhs, T const & rhs)
1676         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1677 
1678         template<typename T>
1679         inline bool                                operator != (::std::complex<T> const & lhs, octonion<T> const & rhs)
1680         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1681 
1682         template<typename T>
1683         inline bool                                operator != (octonion<T> const & lhs, ::std::complex<T> const & rhs)
1684         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1685 
1686         template<typename T>
1687         inline bool                                operator != (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs)
1688         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1689 
1690         template<typename T>
1691         inline bool                                operator != (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs)
1692         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1693 
1694         template<typename T>
1695         inline bool                                operator != (octonion<T> const & lhs, octonion<T> const & rhs)
1696         BOOST_OCTONION_NOT_EQUAL_GENERATOR
1697 
1698     #undef    BOOST_OCTONION_NOT_EQUAL_GENERATOR
1699 
1700 
1701         // Note:    the default values in the constructors of the complex and quaternions make for
1702         //            a very complex and ambiguous situation; we have made choices to disambiguate.
1703         template<typename T, typename charT, class traits>
1704         ::std::basic_istream<charT,traits> &    operator >> (    ::std::basic_istream<charT,traits> & is,
1705                                                                 octonion<T> & o)
1706         {
1707 #ifdef     BOOST_NO_STD_LOCALE
1708 #else
1709             const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc());
1710 #endif /* BOOST_NO_STD_LOCALE */
1711 
1712             T    a = T();
1713             T    b = T();
1714             T    c = T();
1715             T    d = T();
1716             T    e = T();
1717             T    f = T();
1718             T    g = T();
1719             T    h = T();
1720 
1721             ::std::complex<T>    u = ::std::complex<T>();
1722             ::std::complex<T>    v = ::std::complex<T>();
1723             ::std::complex<T>    x = ::std::complex<T>();
1724             ::std::complex<T>    y = ::std::complex<T>();
1725 
1726             ::boost::math::quaternion<T>    p = ::boost::math::quaternion<T>();
1727             ::boost::math::quaternion<T>    q = ::boost::math::quaternion<T>();
1728 
1729             charT    ch = charT();
1730             char    cc;
1731 
1732             is >> ch;                                        // get the first lexeme
1733 
1734             if    (!is.good())    goto finish;
1735 
1736 #ifdef    BOOST_NO_STD_LOCALE
1737             cc = ch;
1738 #else
1739             cc = ct.narrow(ch, char());
1740 #endif /* BOOST_NO_STD_LOCALE */
1741 
1742             if    (cc == '(')                            // read "("
1743             {
1744                 is >> ch;                                    // get the second lexeme
1745 
1746                 if    (!is.good())    goto finish;
1747 
1748 #ifdef    BOOST_NO_STD_LOCALE
1749                 cc = ch;
1750 #else
1751                 cc = ct.narrow(ch, char());
1752 #endif /* BOOST_NO_STD_LOCALE */
1753 
1754                 if    (cc == '(')                                // read "(("
1755                 {
1756                     is >> ch;                                    // get the third lexeme
1757 
1758                     if    (!is.good())    goto finish;
1759 
1760 #ifdef    BOOST_NO_STD_LOCALE
1761                     cc = ch;
1762 #else
1763                     cc = ct.narrow(ch, char());
1764 #endif /* BOOST_NO_STD_LOCALE */
1765 
1766                     if    (cc == '(')                                // read "((("
1767                     {
1768                         is.putback(ch);
1769 
1770                         is >> u;                                // read "((u"
1771 
1772                         if    (!is.good())    goto finish;
1773 
1774                         is >> ch;                                // get the next lexeme
1775 
1776                         if    (!is.good())    goto finish;
1777 
1778 #ifdef    BOOST_NO_STD_LOCALE
1779                         cc = ch;
1780 #else
1781                         cc = ct.narrow(ch, char());
1782 #endif /* BOOST_NO_STD_LOCALE */
1783 
1784                         if        (cc == ')')                        // read "((u)"
1785                         {
1786                             is >> ch;                                // get the next lexeme
1787 
1788                             if    (!is.good())    goto finish;
1789 
1790 #ifdef    BOOST_NO_STD_LOCALE
1791                             cc = ch;
1792 #else
1793                             cc = ct.narrow(ch, char());
1794 #endif /* BOOST_NO_STD_LOCALE */
1795 
1796                             if        (cc == ')')                        // format: (((a))), (((a,b)))
1797                             {
1798                                 o = octonion<T>(u);
1799                             }
1800                             else if    (cc == ',')                        // read "((u),"
1801                             {
1802                                 p = ::boost::math::quaternion<T>(u);
1803 
1804                                 is >> q;                                // read "((u),q"
1805 
1806                                 if    (!is.good())    goto finish;
1807 
1808                                 is >> ch;                                // get the next lexeme
1809 
1810                                 if    (!is.good())    goto finish;
1811 
1812 #ifdef    BOOST_NO_STD_LOCALE
1813                                 cc = ch;
1814 #else
1815                                 cc = ct.narrow(ch, char());
1816 #endif /* BOOST_NO_STD_LOCALE */
1817 
1818                                 if        (cc == ')')                        // format: (((a)),q), (((a,b)),q)
1819                                 {
1820                                     o = octonion<T>(p,q);
1821                                 }
1822                                 else                                    // error
1823                                 {
1824                                     is.setstate(::std::ios_base::failbit);
1825                                 }
1826                             }
1827                             else                                    // error
1828                             {
1829                                 is.setstate(::std::ios_base::failbit);
1830                             }
1831                         }
1832                         else if    (cc ==',')                        // read "((u,"
1833                         {
1834                             is >> v;                                // read "((u,v"
1835 
1836                             if    (!is.good())    goto finish;
1837 
1838                             is >> ch;                                // get the next lexeme
1839 
1840                             if    (!is.good())    goto finish;
1841 
1842 #ifdef    BOOST_NO_STD_LOCALE
1843                             cc = ch;
1844 #else
1845                             cc = ct.narrow(ch, char());
1846 #endif /* BOOST_NO_STD_LOCALE */
1847 
1848                             if        (cc == ')')                        // read "((u,v)"
1849                             {
1850                                 p = ::boost::math::quaternion<T>(u,v);
1851 
1852                                 is >> ch;                                // get the next lexeme
1853 
1854                                 if    (!is.good())    goto finish;
1855 
1856 #ifdef    BOOST_NO_STD_LOCALE
1857                                 cc = ch;
1858 #else
1859                                 cc = ct.narrow(ch, char());
1860 #endif /* BOOST_NO_STD_LOCALE */
1861 
1862                                 if        (cc == ')')                        // format: (((a),v)), (((a,b),v))
1863                                 {
1864                                     o = octonion<T>(p);
1865                                 }
1866                                 else if    (cc == ',')                        // read "((u,v),"
1867                                 {
1868                                     is >> q;                                // read "(p,q"
1869 
1870                                     if    (!is.good())    goto finish;
1871 
1872                                     is >> ch;                                // get the next lexeme
1873 
1874                                     if    (!is.good())    goto finish;
1875 
1876 #ifdef    BOOST_NO_STD_LOCALE
1877                                     cc = ch;
1878 #else
1879                                     cc = ct.narrow(ch, char());
1880 #endif /* BOOST_NO_STD_LOCALE */
1881 
1882                                     if        (cc == ')')                        // format: (((a),v),q), (((a,b),v),q)
1883                                     {
1884                                         o = octonion<T>(p,q);
1885                                     }
1886                                     else                                    // error
1887                                     {
1888                                         is.setstate(::std::ios_base::failbit);
1889                                     }
1890                                 }
1891                                 else                                    // error
1892                                 {
1893                                     is.setstate(::std::ios_base::failbit);
1894                                 }
1895                             }
1896                             else                                    // error
1897                             {
1898                                 is.setstate(::std::ios_base::failbit);
1899                             }
1900                         }
1901                         else                                    // error
1902                         {
1903                             is.setstate(::std::ios_base::failbit);
1904                         }
1905                     }
1906                     else                                        // read "((a"
1907                     {
1908                         is.putback(ch);
1909 
1910                         is >> a;                                    // we extract the first component
1911 
1912                         if    (!is.good())    goto finish;
1913 
1914                         is >> ch;                                    // get the next lexeme
1915 
1916                         if    (!is.good())    goto finish;
1917 
1918 #ifdef    BOOST_NO_STD_LOCALE
1919                         cc = ch;
1920 #else
1921                         cc = ct.narrow(ch, char());
1922 #endif /* BOOST_NO_STD_LOCALE */
1923 
1924                         if        (cc == ')')                            // read "((a)"
1925                         {
1926                             is >> ch;                                    // get the next lexeme
1927 
1928                             if    (!is.good())    goto finish;
1929 
1930 #ifdef    BOOST_NO_STD_LOCALE
1931                             cc = ch;
1932 #else
1933                             cc = ct.narrow(ch, char());
1934 #endif /* BOOST_NO_STD_LOCALE */
1935 
1936                             if        (cc == ')')                            // read "((a))"
1937                             {
1938                                 o = octonion<T>(a);
1939                             }
1940                             else if    (cc == ',')                            // read "((a),"
1941                             {
1942                                 is >> ch;                                    // get the next lexeme
1943 
1944                                 if    (!is.good())    goto finish;
1945 
1946 #ifdef    BOOST_NO_STD_LOCALE
1947                                 cc = ch;
1948 #else
1949                                 cc = ct.narrow(ch, char());
1950 #endif /* BOOST_NO_STD_LOCALE */
1951 
1952                                 if        (cc == '(')                            // read "((a),("
1953                                 {
1954                                     is >> ch;                                    // get the next lexeme
1955 
1956                                     if    (!is.good())    goto finish;
1957 
1958 #ifdef    BOOST_NO_STD_LOCALE
1959                                     cc = ch;
1960 #else
1961                                     cc = ct.narrow(ch, char());
1962 #endif /* BOOST_NO_STD_LOCALE */
1963 
1964                                     if        (cc == '(')                            // read "((a),(("
1965                                     {
1966                                         is.putback(ch);
1967 
1968                                         is.putback(ch);                                // we backtrack twice, with the same value!
1969 
1970                                         is >> q;                                    // read "((a),q"
1971 
1972                                         if    (!is.good())    goto finish;
1973 
1974                                         is >> ch;                                    // get the next lexeme
1975 
1976                                         if    (!is.good())    goto finish;
1977 
1978 #ifdef    BOOST_NO_STD_LOCALE
1979                                         cc = ch;
1980 #else
1981                                         cc = ct.narrow(ch, char());
1982 #endif /* BOOST_NO_STD_LOCALE */
1983 
1984                                         if        (cc == ')')                            // read "((a),q)"
1985                                         {
1986                                             p = ::boost::math::quaternion<T>(a);
1987 
1988                                             o = octonion<T>(p,q);
1989                                         }
1990                                         else                                        // error
1991                                         {
1992                                             is.setstate(::std::ios_base::failbit);
1993                                         }
1994                                     }
1995                                     else                                        // read "((a),(c" or "((a),(e"
1996                                     {
1997                                         is.putback(ch);
1998 
1999                                         is >> c;
2000 
2001                                         if    (!is.good())    goto finish;
2002 
2003                                         is >> ch;                                    // get the next lexeme
2004 
2005                                         if    (!is.good())    goto finish;
2006 
2007 #ifdef    BOOST_NO_STD_LOCALE
2008                                         cc = ch;
2009 #else
2010                                         cc = ct.narrow(ch, char());
2011 #endif /* BOOST_NO_STD_LOCALE */
2012 
2013                                         if        (cc == ')')                            // read "((a),(c)" (ambiguity resolution)
2014                                         {
2015                                             is >> ch;                                    // get the next lexeme
2016 
2017                                             if    (!is.good())    goto finish;
2018 
2019 #ifdef    BOOST_NO_STD_LOCALE
2020                                             cc = ch;
2021 #else
2022                                             cc = ct.narrow(ch, char());
2023 #endif /* BOOST_NO_STD_LOCALE */
2024 
2025                                             if        (cc == ')')                        // read "((a),(c))"
2026                                             {
2027                                                 o = octonion<T>(a,b,c);
2028                                             }
2029                                             else if    (cc == ',')                        // read "((a),(c),"
2030                                             {
2031                                                 u = ::std::complex<T>(a);
2032 
2033                                                 v = ::std::complex<T>(c);
2034 
2035                                                 is >> x;                            // read "((a),(c),x"
2036 
2037                                                 if    (!is.good())    goto finish;
2038 
2039                                                 is >> ch;                                // get the next lexeme
2040 
2041                                                 if    (!is.good())    goto finish;
2042 
2043 #ifdef    BOOST_NO_STD_LOCALE
2044                                                 cc = ch;
2045 #else
2046                                                 cc = ct.narrow(ch, char());
2047 #endif /* BOOST_NO_STD_LOCALE */
2048 
2049                                                 if        (cc == ')')                        // read "((a),(c),x)"
2050                                                 {
2051                                                     o = octonion<T>(u,v,x);
2052                                                 }
2053                                                 else if    (cc == ',')                        // read "((a),(c),x,"
2054                                                 {
2055                                                     is >> y;                                // read "((a),(c),x,y"
2056 
2057                                                     if    (!is.good())    goto finish;
2058 
2059                                                     is >> ch;                                // get the next lexeme
2060 
2061                                                     if    (!is.good())    goto finish;
2062 
2063 #ifdef    BOOST_NO_STD_LOCALE
2064                                                     cc = ch;
2065 #else
2066                                                     cc = ct.narrow(ch, char());
2067 #endif /* BOOST_NO_STD_LOCALE */
2068 
2069                                                     if        (cc == ')')                        // read "((a),(c),x,y)"
2070                                                     {
2071                                                         o = octonion<T>(u,v,x,y);
2072                                                     }
2073                                                     else                                    // error
2074                                                     {
2075                                                         is.setstate(::std::ios_base::failbit);
2076                                                     }
2077                                                 }
2078                                                 else                                    // error
2079                                                 {
2080                                                     is.setstate(::std::ios_base::failbit);
2081                                                 }
2082                                             }
2083                                             else                                    // error
2084                                             {
2085                                                 is.setstate(::std::ios_base::failbit);
2086                                             }
2087                                         }
2088                                         else if    (cc == ',')                            // read "((a),(c," or "((a),(e,"
2089                                         {
2090                                             is >> ch;                                // get the next lexeme
2091 
2092                                             if    (!is.good())    goto finish;
2093 
2094 #ifdef    BOOST_NO_STD_LOCALE
2095                                             cc = ch;
2096 #else
2097                                             cc = ct.narrow(ch, char());
2098 #endif /* BOOST_NO_STD_LOCALE */
2099 
2100                                             if        (cc == '(')                        // read "((a),(e,(" (ambiguity resolution)
2101                                             {
2102                                                 p = ::boost::math::quaternion<T>(a);
2103 
2104                                                 x = ::std::complex<T>(c);                // "c" was actually "e"
2105 
2106                                                 is.putback(ch);                            // we can only backtrace once
2107 
2108                                                 is >> y;                                // read "((a),(e,y"
2109 
2110                                                 if    (!is.good())    goto finish;
2111 
2112                                                 is >> ch;                                // get the next lexeme
2113 
2114 #ifdef    BOOST_NO_STD_LOCALE
2115                                                 cc = ch;
2116 #else
2117                                                 cc = ct.narrow(ch, char());
2118 #endif /* BOOST_NO_STD_LOCALE */
2119 
2120                                                 if        (cc == ')')                        // read "((a),(e,y)"
2121                                                 {
2122                                                     q = ::boost::math::quaternion<T>(x,y);
2123 
2124                                                     is >> ch;                                // get the next lexeme
2125 
2126 #ifdef    BOOST_NO_STD_LOCALE
2127                                                     cc = ch;
2128 #else
2129                                                     cc = ct.narrow(ch, char());
2130 #endif /* BOOST_NO_STD_LOCALE */
2131 
2132                                                     if        (cc == ')')                        // read "((a),(e,y))"
2133                                                     {
2134                                                         o = octonion<T>(p,q);
2135                                                     }
2136                                                     else                                    // error
2137                                                     {
2138                                                         is.setstate(::std::ios_base::failbit);
2139                                                     }
2140                                                 }
2141                                                 else                                    // error
2142                                                 {
2143                                                     is.setstate(::std::ios_base::failbit);
2144                                                 }
2145                                             }
2146                                             else                                    // read "((a),(c,d" or "((a),(e,f"
2147                                             {
2148                                                 is.putback(ch);
2149 
2150                                                 is >> d;
2151 
2152                                                 if    (!is.good())    goto finish;
2153 
2154                                                 is >> ch;                                // get the next lexeme
2155 
2156                                                 if    (!is.good())    goto finish;
2157 
2158 #ifdef    BOOST_NO_STD_LOCALE
2159                                                 cc = ch;
2160 #else
2161                                                 cc = ct.narrow(ch, char());
2162 #endif /* BOOST_NO_STD_LOCALE */
2163 
2164                                                 if        (cc == ')')                        // read "((a),(c,d)" (ambiguity resolution)
2165                                                 {
2166                                                     is >> ch;                                // get the next lexeme
2167 
2168                                                     if    (!is.good())    goto finish;
2169 
2170 #ifdef    BOOST_NO_STD_LOCALE
2171                                                     cc = ch;
2172 #else
2173                                                     cc = ct.narrow(ch, char());
2174 #endif /* BOOST_NO_STD_LOCALE */
2175 
2176                                                     if        (cc == ')')                        // read "((a),(c,d))"
2177                                                     {
2178                                                         o = octonion<T>(a,b,c,d);
2179                                                     }
2180                                                     else if    (cc == ',')                        // read "((a),(c,d),"
2181                                                     {
2182                                                         u = ::std::complex<T>(a);
2183 
2184                                                         v = ::std::complex<T>(c,d);
2185 
2186                                                         is >> x;                                // read "((a),(c,d),x"
2187 
2188                                                         if    (!is.good())    goto finish;
2189 
2190                                                         is >> ch;                                // get the next lexeme
2191 
2192                                                         if    (!is.good())    goto finish;
2193 
2194 #ifdef    BOOST_NO_STD_LOCALE
2195                                                         cc = ch;
2196 #else
2197                                                         cc = ct.narrow(ch, char());
2198 #endif /* BOOST_NO_STD_LOCALE */
2199 
2200                                                         if        (cc == ')')                        // read "((a),(c,d),x)"
2201                                                         {
2202                                                             o = octonion<T>(u,v,x);
2203                                                         }
2204                                                         else if    (cc == ',')                        // read "((a),(c,d),x,"
2205                                                         {
2206                                                             is >> y;                                // read "((a),(c,d),x,y"
2207 
2208                                                             if    (!is.good())    goto finish;
2209 
2210                                                             is >> ch;                                // get the next lexeme
2211 
2212                                                             if    (!is.good())    goto finish;
2213 
2214 #ifdef    BOOST_NO_STD_LOCALE
2215                                                             cc = ch;
2216 #else
2217                                                             cc = ct.narrow(ch, char());
2218 #endif /* BOOST_NO_STD_LOCALE */
2219 
2220                                                             if        (cc == ')')                        // read "((a),(c,d),x,y)"
2221                                                             {
2222                                                                 o = octonion<T>(u,v,x,y);
2223                                                             }
2224                                                             else                                    // error
2225                                                             {
2226                                                                 is.setstate(::std::ios_base::failbit);
2227                                                             }
2228                                                         }
2229                                                         else                                    // error
2230                                                         {
2231                                                             is.setstate(::std::ios_base::failbit);
2232                                                         }
2233                                                     }
2234                                                     else                                    // error
2235                                                     {
2236                                                         is.setstate(::std::ios_base::failbit);
2237                                                     }
2238                                                 }
2239                                                 else if    (cc == ',')                        // read "((a),(e,f," (ambiguity resolution)
2240                                                 {
2241                                                     p = ::boost::math::quaternion<T>(a);
2242 
2243                                                     is >> g;                                // read "((a),(e,f,g" (too late to backtrack)
2244 
2245                                                     if    (!is.good())    goto finish;
2246 
2247                                                     is >> ch;                                // get the next lexeme
2248 
2249                                                     if    (!is.good())    goto finish;
2250 
2251 #ifdef    BOOST_NO_STD_LOCALE
2252                                                     cc = ch;
2253 #else
2254                                                     cc = ct.narrow(ch, char());
2255 #endif /* BOOST_NO_STD_LOCALE */
2256 
2257                                                     if        (cc == ')')                        // read "((a),(e,f,g)"
2258                                                     {
2259                                                         q = ::boost::math::quaternion<T>(c,d,g);        // "c" was actually "e", and "d" was actually "f"
2260 
2261                                                         is >> ch;                                // get the next lexeme
2262 
2263                                                         if    (!is.good())    goto finish;
2264 
2265 #ifdef    BOOST_NO_STD_LOCALE
2266                                                         cc = ch;
2267 #else
2268                                                         cc = ct.narrow(ch, char());
2269 #endif /* BOOST_NO_STD_LOCALE */
2270 
2271                                                         if        (cc == ')')                        // read "((a),(e,f,g))"
2272                                                         {
2273                                                             o = octonion<T>(p,q);
2274                                                         }
2275                                                         else                                    // error
2276                                                         {
2277                                                             is.setstate(::std::ios_base::failbit);
2278                                                         }
2279                                                     }
2280                                                     else if    (cc == ',')                        // read "((a),(e,f,g,"
2281                                                     {
2282                                                         is >> h;                                // read "((a),(e,f,g,h"
2283 
2284                                                         if    (!is.good())    goto finish;
2285 
2286                                                         is >> ch;                                // get the next lexeme
2287 
2288                                                         if    (!is.good())    goto finish;
2289 
2290 #ifdef    BOOST_NO_STD_LOCALE
2291                                                         cc = ch;
2292 #else
2293                                                         cc = ct.narrow(ch, char());
2294 #endif /* BOOST_NO_STD_LOCALE */
2295 
2296                                                         if        (cc == ')')                        // read "((a),(e,f,g,h)"
2297                                                         {
2298                                                             q = ::boost::math::quaternion<T>(c,d,g,h);    // "c" was actually "e", and "d" was actually "f"
2299 
2300                                                             is >> ch;                                // get the next lexeme
2301 
2302                                                             if    (!is.good())    goto finish;
2303 
2304 #ifdef    BOOST_NO_STD_LOCALE
2305                                                             cc = ch;
2306 #else
2307                                                             cc = ct.narrow(ch, char());
2308 #endif /* BOOST_NO_STD_LOCALE */
2309 
2310                                                             if        (cc == ')')                        // read "((a),(e,f,g,h))"
2311                                                             {
2312                                                                 o = octonion<T>(p,q);
2313                                                             }
2314                                                             else                                    // error
2315                                                             {
2316                                                                 is.setstate(::std::ios_base::failbit);
2317                                                             }
2318                                                         }
2319                                                         else                                    // error
2320                                                         {
2321                                                             is.setstate(::std::ios_base::failbit);
2322                                                         }
2323                                                     }
2324                                                     else                                    // error
2325                                                     {
2326                                                         is.setstate(::std::ios_base::failbit);
2327                                                     }
2328                                                 }
2329                                                 else                                    // error
2330                                                 {
2331                                                     is.setstate(::std::ios_base::failbit);
2332                                                 }
2333                                             }
2334                                         }
2335                                         else                                        // error
2336                                         {
2337                                             is.setstate(::std::ios_base::failbit);
2338                                         }
2339                                     }
2340                                 }
2341                                 else                                        // read "((a),c" (ambiguity resolution)
2342                                 {
2343                                     is.putback(ch);
2344 
2345                                     is >> c;                                    // we extract the third component
2346 
2347                                     if    (!is.good())    goto finish;
2348 
2349                                     is >> ch;                                    // get the next lexeme
2350 
2351                                     if    (!is.good())    goto finish;
2352 
2353 #ifdef    BOOST_NO_STD_LOCALE
2354                                     cc = ch;
2355 #else
2356                                     cc = ct.narrow(ch, char());
2357 #endif /* BOOST_NO_STD_LOCALE */
2358 
2359                                     if        (cc == ')')                            // read "((a),c)"
2360                                     {
2361                                         o = octonion<T>(a,b,c);
2362                                     }
2363                                     else if    (cc == ',')                            // read "((a),c,"
2364                                     {
2365                                         is >> x;                                    // read "((a),c,x"
2366 
2367                                         if    (!is.good())    goto finish;
2368 
2369                                         is >> ch;                                    // get the next lexeme
2370 
2371                                         if    (!is.good())    goto finish;
2372 
2373 #ifdef    BOOST_NO_STD_LOCALE
2374                                         cc = ch;
2375 #else
2376                                         cc = ct.narrow(ch, char());
2377 #endif /* BOOST_NO_STD_LOCALE */
2378 
2379                                         if        (cc == ')')                            // read "((a),c,x)"
2380                                         {
2381                                             o = octonion<T>(a,b,c,d,x.real(),x.imag());
2382                                         }
2383                                         else if    (cc == ',')                            // read "((a),c,x,"
2384                                         {
2385                                             is >> y;if    (!is.good())    goto finish;        // read "((a),c,x,y"
2386 
2387                                             is >> ch;                                    // get the next lexeme
2388 
2389                                             if    (!is.good())    goto finish;
2390 
2391 #ifdef    BOOST_NO_STD_LOCALE
2392                                             cc = ch;
2393 #else
2394                                             cc = ct.narrow(ch, char());
2395 #endif /* BOOST_NO_STD_LOCALE */
2396 
2397                                             if        (cc == ')')                            // read "((a),c,x,y)"
2398                                             {
2399                                                 o = octonion<T>(a,b,c,d,x.real(),x.imag(),y.real(),y.imag());
2400                                             }
2401                                             else                                        // error
2402                                             {
2403                                                 is.setstate(::std::ios_base::failbit);
2404                                             }
2405                                         }
2406                                         else                                        // error
2407                                         {
2408                                             is.setstate(::std::ios_base::failbit);
2409                                         }
2410                                     }
2411                                     else                                        // error
2412                                     {
2413                                         is.setstate(::std::ios_base::failbit);
2414                                     }
2415                                 }
2416                             }
2417                             else                                        // error
2418                             {
2419                                 is.setstate(::std::ios_base::failbit);
2420                             }
2421                         }
2422                         else if    (cc ==',')                            // read "((a,"
2423                         {
2424                             is >> ch;                                    // get the next lexeme
2425 
2426                             if    (!is.good())    goto finish;
2427 
2428 #ifdef    BOOST_NO_STD_LOCALE
2429                             cc = ch;
2430 #else
2431                             cc = ct.narrow(ch, char());
2432 #endif /* BOOST_NO_STD_LOCALE */
2433 
2434                             if        (cc == '(')                            // read "((a,("
2435                             {
2436                                 u = ::std::complex<T>(a);
2437 
2438                                 is.putback(ch);                                // can only backtrack so much
2439 
2440                                 is >> v;                                    // read "((a,v"
2441 
2442                                 if    (!is.good())    goto finish;
2443 
2444                                 is >> ch;                                    // get the next lexeme
2445 
2446                                 if    (!is.good())    goto finish;
2447 
2448 #ifdef    BOOST_NO_STD_LOCALE
2449                                 cc = ch;
2450 #else
2451                                 cc = ct.narrow(ch, char());
2452 #endif /* BOOST_NO_STD_LOCALE */
2453 
2454                                 if        (cc == ')')                            // read "((a,v)"
2455                                 {
2456                                     is >> ch;                                    // get the next lexeme
2457 
2458                                     if    (!is.good())    goto finish;
2459 
2460 #ifdef    BOOST_NO_STD_LOCALE
2461                                     cc = ch;
2462 #else
2463                                     cc = ct.narrow(ch, char());
2464 #endif /* BOOST_NO_STD_LOCALE */
2465 
2466                                     if        (cc == ')')                            // read "((a,v))"
2467                                     {
2468                                         o = octonion<T>(u,v);
2469                                     }
2470                                     else if    (cc == ',')                            // read "((a,v),"
2471                                     {
2472                                         p = ::boost::math::quaternion<T>(u,v);
2473 
2474                                         is >> q;                                    // read "((a,v),q"
2475 
2476                                         if    (!is.good())    goto finish;
2477 
2478                                         is >> ch;                                    // get the next lexeme
2479 
2480                                         if    (!is.good())    goto finish;
2481 
2482 #ifdef    BOOST_NO_STD_LOCALE
2483                                         cc = ch;
2484 #else
2485                                         cc = ct.narrow(ch, char());
2486 #endif /* BOOST_NO_STD_LOCALE */
2487 
2488                                         if        (cc == ')')                            // read "((a,v),q)"
2489                                         {
2490                                             o = octonion<T>(p,q);
2491                                         }
2492                                         else                                        // error
2493                                         {
2494                                             is.setstate(::std::ios_base::failbit);
2495                                         }
2496                                     }
2497                                     else                                        // error
2498                                     {
2499                                         is.setstate(::std::ios_base::failbit);
2500                                     }
2501                                 }
2502                                 else                                        // error
2503                                 {
2504                                     is.setstate(::std::ios_base::failbit);
2505                                 }
2506                             }
2507                             else
2508                             {
2509                                 is.putback(ch);
2510 
2511                                 is >> b;                                    // read "((a,b"
2512 
2513                                 if    (!is.good())    goto finish;
2514 
2515                                 is >> ch;                                    // get the next lexeme
2516 
2517                                 if    (!is.good())    goto finish;
2518 
2519 #ifdef    BOOST_NO_STD_LOCALE
2520                                 cc = ch;
2521 #else
2522                                 cc = ct.narrow(ch, char());
2523 #endif /* BOOST_NO_STD_LOCALE */
2524 
2525                                 if        (cc == ')')                            // read "((a,b)"
2526                                 {
2527                                     is >> ch;                                    // get the next lexeme
2528 
2529                                     if    (!is.good())    goto finish;
2530 
2531 #ifdef    BOOST_NO_STD_LOCALE
2532                                     cc = ch;
2533 #else
2534                                     cc = ct.narrow(ch, char());
2535 #endif /* BOOST_NO_STD_LOCALE */
2536 
2537                                     if        (cc == ')')                            // read "((a,b))"
2538                                     {
2539                                         o = octonion<T>(a,b);
2540                                     }
2541                                     else if    (cc == ',')                            // read "((a,b),"
2542                                     {
2543                                         is >> ch;                                    // get the next lexeme
2544 
2545                                         if    (!is.good())    goto finish;
2546 
2547 #ifdef    BOOST_NO_STD_LOCALE
2548                                         cc = ch;
2549 #else
2550                                         cc = ct.narrow(ch, char());
2551 #endif /* BOOST_NO_STD_LOCALE */
2552 
2553                                         if        (cc == '(')                            // read "((a,b),("
2554                                         {
2555                                             is >> ch;                                    // get the next lexeme
2556 
2557                                             if    (!is.good())    goto finish;
2558 
2559 #ifdef    BOOST_NO_STD_LOCALE
2560                                             cc = ch;
2561 #else
2562                                             cc = ct.narrow(ch, char());
2563 #endif /* BOOST_NO_STD_LOCALE */
2564 
2565                                             if        (cc == '(')                            // read "((a,b),(("
2566                                             {
2567                                                 p = ::boost::math::quaternion<T>(a,b);
2568 
2569                                                 is.putback(ch);
2570 
2571                                                 is.putback(ch);                            // we backtrack twice, with the same value
2572 
2573                                                 is >> q;                                // read "((a,b),q"
2574 
2575                                                 if    (!is.good())    goto finish;
2576 
2577                                                 is >> ch;                                    // get the next lexeme
2578 
2579                                                 if    (!is.good())    goto finish;
2580 
2581 #ifdef    BOOST_NO_STD_LOCALE
2582                                                 cc = ch;
2583 #else
2584                                                 cc = ct.narrow(ch, char());
2585 #endif /* BOOST_NO_STD_LOCALE */
2586 
2587                                                 if        (cc == ')')                            // read "((a,b),q)"
2588                                                 {
2589                                                     o = octonion<T>(p,q);
2590                                                 }
2591                                                 else                                        // error
2592                                                 {
2593                                                     is.setstate(::std::ios_base::failbit);
2594                                                 }
2595                                             }
2596                                             else                                        // read "((a,b),(c" or "((a,b),(e"
2597                                             {
2598                                                 is.putback(ch);
2599 
2600                                                 is >> c;
2601 
2602                                                 if    (!is.good())    goto finish;
2603 
2604                                                 is >> ch;                                    // get the next lexeme
2605 
2606                                                 if    (!is.good())    goto finish;
2607 
2608 #ifdef    BOOST_NO_STD_LOCALE
2609                                                 cc = ch;
2610 #else
2611                                                 cc = ct.narrow(ch, char());
2612 #endif /* BOOST_NO_STD_LOCALE */
2613 
2614                                                 if        (cc == ')')                            // read "((a,b),(c)" (ambiguity resolution)
2615                                                 {
2616                                                     is >> ch;                                    // get the next lexeme
2617 
2618                                                     if    (!is.good())    goto finish;
2619 
2620 #ifdef    BOOST_NO_STD_LOCALE
2621                                                     cc = ch;
2622 #else
2623                                                     cc = ct.narrow(ch, char());
2624 #endif /* BOOST_NO_STD_LOCALE */
2625 
2626                                                     if        (cc == ')')                            // read "((a,b),(c))"
2627                                                     {
2628                                                         o = octonion<T>(a,b,c);
2629                                                     }
2630                                                     else if    (cc == ',')                            // read "((a,b),(c),"
2631                                                     {
2632                                                         u = ::std::complex<T>(a,b);
2633 
2634                                                         v = ::std::complex<T>(c);
2635 
2636                                                         is >> x;                                    // read "((a,b),(c),x"
2637 
2638                                                         if    (!is.good())    goto finish;
2639 
2640                                                         is >> ch;                                    // get the next lexeme
2641 
2642                                                         if    (!is.good())    goto finish;
2643 
2644 #ifdef    BOOST_NO_STD_LOCALE
2645                                                         cc = ch;
2646 #else
2647                                                         cc = ct.narrow(ch, char());
2648 #endif /* BOOST_NO_STD_LOCALE */
2649 
2650                                                         if        (cc == ')')                            // read "((a,b),(c),x)"
2651                                                         {
2652                                                             o = octonion<T>(u,v,x);
2653                                                         }
2654                                                         else if    (cc == ',')                            // read "((a,b),(c),x,"
2655                                                         {
2656                                                             is >> y;                                    // read "((a,b),(c),x,y"
2657 
2658                                                             if    (!is.good())    goto finish;
2659 
2660                                                             is >> ch;                                    // get the next lexeme
2661 
2662                                                             if    (!is.good())    goto finish;
2663 
2664 #ifdef    BOOST_NO_STD_LOCALE
2665                                                             cc = ch;
2666 #else
2667                                                             cc = ct.narrow(ch, char());
2668 #endif /* BOOST_NO_STD_LOCALE */
2669 
2670                                                             if        (cc == ')')                            // read "((a,b),(c),x,y)"
2671                                                             {
2672                                                                 o = octonion<T>(u,v,x,y);
2673                                                             }
2674                                                             else                                        // error
2675                                                             {
2676                                                                 is.setstate(::std::ios_base::failbit);
2677                                                             }
2678                                                         }
2679                                                         else                                        // error
2680                                                         {
2681                                                             is.setstate(::std::ios_base::failbit);
2682                                                         }
2683                                                     }
2684                                                     else                                        // error
2685                                                     {
2686                                                         is.setstate(::std::ios_base::failbit);
2687                                                     }
2688                                                 }
2689                                                 else if    (cc == ',')                            // read "((a,b),(c," or "((a,b),(e,"
2690                                                 {
2691                                                     is >> ch;                                    // get the next lexeme
2692 
2693                                                     if    (!is.good())    goto finish;
2694 
2695 #ifdef    BOOST_NO_STD_LOCALE
2696                                                     cc = ch;
2697 #else
2698                                                     cc = ct.narrow(ch, char());
2699 #endif /* BOOST_NO_STD_LOCALE */
2700 
2701                                                     if        (cc == '(')                            // read "((a,b),(e,(" (ambiguity resolution)
2702                                                     {
2703                                                         u = ::std::complex<T>(a,b);
2704 
2705                                                         x = ::std::complex<T>(c);                    // "c" is actually "e"
2706 
2707                                                         is.putback(ch);
2708 
2709                                                         is >> y;                                    // read "((a,b),(e,y"
2710 
2711                                                         if    (!is.good())    goto finish;
2712 
2713                                                         is >> ch;                                    // get the next lexeme
2714 
2715                                                         if    (!is.good())    goto finish;
2716 
2717 #ifdef    BOOST_NO_STD_LOCALE
2718                                                         cc = ch;
2719 #else
2720                                                         cc = ct.narrow(ch, char());
2721 #endif /* BOOST_NO_STD_LOCALE */
2722 
2723                                                         if        (cc == ')')                            // read "((a,b),(e,y)"
2724                                                         {
2725                                                             is >> ch;                                    // get the next lexeme
2726 
2727                                                             if    (!is.good())    goto finish;
2728 
2729 #ifdef    BOOST_NO_STD_LOCALE
2730                                                             cc = ch;
2731 #else
2732                                                             cc = ct.narrow(ch, char());
2733 #endif /* BOOST_NO_STD_LOCALE */
2734 
2735                                                             if        (cc == ')')                            // read "((a,b),(e,y))"
2736                                                             {
2737                                                                 o = octonion<T>(u,v,x,y);
2738                                                             }
2739                                                             else                                        // error
2740                                                             {
2741                                                                 is.setstate(::std::ios_base::failbit);
2742                                                             }
2743                                                         }
2744                                                         else                                        // error
2745                                                         {
2746                                                             is.setstate(::std::ios_base::failbit);
2747                                                         }
2748                                                     }
2749                                                     else                                        // read "((a,b),(c,d" or "((a,b),(e,f"
2750                                                     {
2751                                                         is.putback(ch);
2752 
2753                                                         is >> d;
2754 
2755                                                         if    (!is.good())    goto finish;
2756 
2757                                                         is >> ch;                                    // get the next lexeme
2758 
2759                                                         if    (!is.good())    goto finish;
2760 
2761 #ifdef    BOOST_NO_STD_LOCALE
2762                                                         cc = ch;
2763 #else
2764                                                         cc = ct.narrow(ch, char());
2765 #endif /* BOOST_NO_STD_LOCALE */
2766 
2767                                                         if        (cc == ')')                            // read "((a,b),(c,d)" (ambiguity resolution)
2768                                                         {
2769                                                             u = ::std::complex<T>(a,b);
2770 
2771                                                             v = ::std::complex<T>(c,d);
2772 
2773                                                             is >> ch;                                    // get the next lexeme
2774 
2775                                                             if    (!is.good())    goto finish;
2776 
2777 #ifdef    BOOST_NO_STD_LOCALE
2778                                                             cc = ch;
2779 #else
2780                                                             cc = ct.narrow(ch, char());
2781 #endif /* BOOST_NO_STD_LOCALE */
2782 
2783                                                             if        (cc == ')')                            // read "((a,b),(c,d))"
2784                                                             {
2785                                                                 o = octonion<T>(u,v);
2786                                                             }
2787                                                             else if    (cc == ',')                            // read "((a,b),(c,d),"
2788                                                             {
2789                                                                 is >> x;                                    // read "((a,b),(c,d),x
2790 
2791                                                                 if    (!is.good())    goto finish;
2792 
2793                                                                 is >> ch;                                    // get the next lexeme
2794 
2795                                                                 if    (!is.good())    goto finish;
2796 
2797 #ifdef    BOOST_NO_STD_LOCALE
2798                                                                 cc = ch;
2799 #else
2800                                                                 cc = ct.narrow(ch, char());
2801 #endif /* BOOST_NO_STD_LOCALE */
2802 
2803                                                                 if        (cc == ')')                            // read "((a,b),(c,d),x)"
2804                                                                 {
2805                                                                     o = octonion<T>(u,v,x);
2806                                                                 }
2807                                                                 else if    (cc == ',')                            // read "((a,b),(c,d),x,"
2808                                                                 {
2809                                                                     is >> y;                                    // read "((a,b),(c,d),x,y"
2810 
2811                                                                     if    (!is.good())    goto finish;
2812 
2813                                                                     is >> ch;                                    // get the next lexeme
2814 
2815                                                                     if    (!is.good())    goto finish;
2816 
2817 #ifdef    BOOST_NO_STD_LOCALE
2818                                                                     cc = ch;
2819 #else
2820                                                                     cc = ct.narrow(ch, char());
2821 #endif /* BOOST_NO_STD_LOCALE */
2822 
2823                                                                     if        (cc == ')')                            // read "((a,b),(c,d),x,y)"
2824                                                                     {
2825                                                                         o = octonion<T>(u,v,x,y);
2826                                                                     }
2827                                                                     else                                        // error
2828                                                                     {
2829                                                                         is.setstate(::std::ios_base::failbit);
2830                                                                     }
2831                                                                 }
2832                                                                 else                                        // error
2833                                                                 {
2834                                                                     is.setstate(::std::ios_base::failbit);
2835                                                                 }
2836                                                             }
2837                                                             else                                        // error
2838                                                             {
2839                                                                 is.setstate(::std::ios_base::failbit);
2840                                                             }
2841                                                         }
2842                                                         else if    (cc == ',')                            // read "((a,b),(e,f," (ambiguity resolution)
2843                                                         {
2844                                                             p = ::boost::math::quaternion<T>(a,b);                // too late to backtrack
2845 
2846                                                             is >> g;                                    // read "((a,b),(e,f,g"
2847 
2848                                                             if    (!is.good())    goto finish;
2849 
2850                                                             is >> ch;                                    // get the next lexeme
2851 
2852                                                             if    (!is.good())    goto finish;
2853 
2854 #ifdef    BOOST_NO_STD_LOCALE
2855                                                             cc = ch;
2856 #else
2857                                                             cc = ct.narrow(ch, char());
2858 #endif /* BOOST_NO_STD_LOCALE */
2859 
2860                                                             if        (cc == ')')                            // read "((a,b),(e,f,g)"
2861                                                             {
2862                                                                 is >> ch;                                    // get the next lexeme
2863 
2864                                                                 if    (!is.good())    goto finish;
2865 
2866 #ifdef    BOOST_NO_STD_LOCALE
2867                                                                 cc = ch;
2868 #else
2869                                                                 cc = ct.narrow(ch, char());
2870 #endif /* BOOST_NO_STD_LOCALE */
2871 
2872                                                                 if        (cc == ')')                            // read "((a,b),(e,f,g))"
2873                                                                 {
2874                                                                     q = ::boost::math::quaternion<T>(c,d,g);            // "c" is actually "e" and "d" is actually "f"
2875 
2876                                                                     o = octonion<T>(p,q);
2877                                                                 }
2878                                                                 else                                        // error
2879                                                                 {
2880                                                                     is.setstate(::std::ios_base::failbit);
2881                                                                 }
2882                                                             }
2883                                                             else if    (cc == ',')                            // read "((a,b),(e,f,g,"
2884                                                             {
2885                                                                 is >> h;                                    // read "((a,b),(e,f,g,h"
2886 
2887                                                                 if    (!is.good())    goto finish;
2888 
2889                                                                 is >> ch;                                    // get the next lexeme
2890 
2891                                                                 if    (!is.good())    goto finish;
2892 
2893 #ifdef    BOOST_NO_STD_LOCALE
2894                                                                 cc = ch;
2895 #else
2896                                                                 cc = ct.narrow(ch, char());
2897 #endif /* BOOST_NO_STD_LOCALE */
2898 
2899                                                                 if        (cc == ')')                            // read "((a,b),(e,f,g,h)"
2900                                                                 {
2901                                                                     is >> ch;                                    // get the next lexeme
2902 
2903                                                                     if    (!is.good())    goto finish;
2904 
2905 #ifdef    BOOST_NO_STD_LOCALE
2906                                                                     cc = ch;
2907 #else
2908                                                                     cc = ct.narrow(ch, char());
2909 #endif /* BOOST_NO_STD_LOCALE */
2910 
2911                                                                     if        (cc == ')')                            // read ((a,b),(e,f,g,h))"
2912                                                                     {
2913                                                                         q = ::boost::math::quaternion<T>(c,d,g,h);            // "c" is actually "e" and "d" is actually "f"
2914 
2915                                                                         o = octonion<T>(p,q);
2916                                                                     }
2917                                                                     else                                        // error
2918                                                                     {
2919                                                                         is.setstate(::std::ios_base::failbit);
2920                                                                     }
2921                                                                 }
2922                                                                 else                                        // error
2923                                                                 {
2924                                                                     is.setstate(::std::ios_base::failbit);
2925                                                                 }
2926                                                             }
2927                                                             else                                        // error
2928                                                             {
2929                                                                 is.setstate(::std::ios_base::failbit);
2930                                                             }
2931                                                         }
2932                                                         else                                        // error
2933                                                         {
2934                                                             is.setstate(::std::ios_base::failbit);
2935                                                         }
2936                                                     }
2937                                                 }
2938                                                 else                                        // error
2939                                                 {
2940                                                     is.setstate(::std::ios_base::failbit);
2941                                                 }
2942                                             }
2943                                         }
2944                                         else                                        // error
2945                                         {
2946                                             is.setstate(::std::ios_base::failbit);
2947                                         }
2948                                     }
2949                                     else                                        // error
2950                                     {
2951                                         is.setstate(::std::ios_base::failbit);
2952                                     }
2953                                 }
2954                                 else if    (cc == ',')                            // read "((a,b,"
2955                                 {
2956                                     is >> c;                                    // read "((a,b,c"
2957 
2958                                     if    (!is.good())    goto finish;
2959 
2960                                     is >> ch;                                    // get the next lexeme
2961 
2962                                     if    (!is.good())    goto finish;
2963 
2964 #ifdef    BOOST_NO_STD_LOCALE
2965                                     cc = ch;
2966 #else
2967                                     cc = ct.narrow(ch, char());
2968 #endif /* BOOST_NO_STD_LOCALE */
2969 
2970                                     if        (cc == ')')                            // read "((a,b,c)"
2971                                     {
2972                                         is >> ch;                                    // get the next lexeme
2973 
2974                                         if    (!is.good())    goto finish;
2975 
2976 #ifdef    BOOST_NO_STD_LOCALE
2977                                         cc = ch;
2978 #else
2979                                         cc = ct.narrow(ch, char());
2980 #endif /* BOOST_NO_STD_LOCALE */
2981 
2982                                         if        (cc == ')')                            // read "((a,b,c))"
2983                                         {
2984                                             o = octonion<T>(a,b,c);
2985                                         }
2986                                         else if    (cc == ',')                            // read "((a,b,c),"
2987                                         {
2988                                             p = ::boost::math::quaternion<T>(a,b,c);
2989 
2990                                             is >> q;                                    // read "((a,b,c),q"
2991 
2992                                             if    (!is.good())    goto finish;
2993 
2994                                             is >> ch;                                    // get the next lexeme
2995 
2996                                             if    (!is.good())    goto finish;
2997 
2998 #ifdef    BOOST_NO_STD_LOCALE
2999                                             cc = ch;
3000 #else
3001                                             cc = ct.narrow(ch, char());
3002 #endif /* BOOST_NO_STD_LOCALE */
3003 
3004                                             if        (cc == ')')                            // read "((a,b,c),q)"
3005                                             {
3006                                                 o = octonion<T>(p,q);
3007                                             }
3008                                             else                                        // error
3009                                             {
3010                                                 is.setstate(::std::ios_base::failbit);
3011                                             }
3012                                         }
3013                                         else                                        // error
3014                                         {
3015                                             is.setstate(::std::ios_base::failbit);
3016                                         }
3017                                     }
3018                                     else if    (cc == ',')                            // read "((a,b,c,"
3019                                     {
3020                                         is >> d;                                    // read "((a,b,c,d"
3021 
3022                                         if    (!is.good())    goto finish;
3023 
3024                                         is >> ch;                                    // get the next lexeme
3025 
3026                                         if    (!is.good())    goto finish;
3027 
3028 #ifdef    BOOST_NO_STD_LOCALE
3029                                         cc = ch;
3030 #else
3031                                         cc = ct.narrow(ch, char());
3032 #endif /* BOOST_NO_STD_LOCALE */
3033 
3034                                         if        (cc == ')')                            // read "((a,b,c,d)"
3035                                         {
3036                                             is >> ch;                                    // get the next lexeme
3037 
3038                                             if    (!is.good())    goto finish;
3039 
3040 #ifdef    BOOST_NO_STD_LOCALE
3041                                             cc = ch;
3042 #else
3043                                             cc = ct.narrow(ch, char());
3044 #endif /* BOOST_NO_STD_LOCALE */
3045 
3046                                             if        (cc == ')')                            // read "((a,b,c,d))"
3047                                             {
3048                                                 o = octonion<T>(a,b,c,d);
3049                                             }
3050                                             else if    (cc == ',')                            // read "((a,b,c,d),"
3051                                             {
3052                                                 p = ::boost::math::quaternion<T>(a,b,c,d);
3053 
3054                                                 is >> q;                                    // read "((a,b,c,d),q"
3055 
3056                                                 if    (!is.good())    goto finish;
3057 
3058                                                 is >> ch;                                    // get the next lexeme
3059 
3060                                                 if    (!is.good())    goto finish;
3061 
3062 #ifdef    BOOST_NO_STD_LOCALE
3063                                                 cc = ch;
3064 #else
3065                                                 cc = ct.narrow(ch, char());
3066 #endif /* BOOST_NO_STD_LOCALE */
3067 
3068                                                 if        (cc == ')')                            // read "((a,b,c,d),q)"
3069                                                 {
3070                                                     o = octonion<T>(p,q);
3071                                                 }
3072                                                 else                                        // error
3073                                                 {
3074                                                     is.setstate(::std::ios_base::failbit);
3075                                                 }
3076                                             }
3077                                             else                                        // error
3078                                             {
3079                                                 is.setstate(::std::ios_base::failbit);
3080                                             }
3081                                         }
3082                                         else                                        // error
3083                                         {
3084                                             is.setstate(::std::ios_base::failbit);
3085                                         }
3086                                     }
3087                                     else                                        // error
3088                                     {
3089                                         is.setstate(::std::ios_base::failbit);
3090                                     }
3091                                 }
3092                                 else                                        // error
3093                                 {
3094                                     is.setstate(::std::ios_base::failbit);
3095                                 }
3096                             }
3097                         }
3098                         else                                        // error
3099                         {
3100                             is.setstate(::std::ios_base::failbit);
3101                         }
3102                     }
3103                 }
3104                 else                                        // read "(a"
3105                 {
3106                     is.putback(ch);
3107 
3108                     is >> a;                                    // we extract the first component
3109 
3110                     if    (!is.good())    goto finish;
3111 
3112                     is >> ch;                                    // get the next lexeme
3113 
3114                     if    (!is.good())    goto finish;
3115 
3116 #ifdef    BOOST_NO_STD_LOCALE
3117                     cc = ch;
3118 #else
3119                     cc = ct.narrow(ch, char());
3120 #endif /* BOOST_NO_STD_LOCALE */
3121 
3122                     if        (cc == ')')                            // read "(a)"
3123                     {
3124                         o = octonion<T>(a);
3125                     }
3126                     else if    (cc == ',')                            // read "(a,"
3127                     {
3128                         is >> ch;                                    // get the next lexeme
3129 
3130                         if    (!is.good())    goto finish;
3131 
3132 #ifdef    BOOST_NO_STD_LOCALE
3133                         cc = ch;
3134 #else
3135                         cc = ct.narrow(ch, char());
3136 #endif /* BOOST_NO_STD_LOCALE */
3137 
3138                         if        (cc == '(')                            // read "(a,("
3139                         {
3140                             is >> ch;                                    // get the next lexeme
3141 
3142                             if    (!is.good())    goto finish;
3143 
3144 #ifdef    BOOST_NO_STD_LOCALE
3145                             cc = ch;
3146 #else
3147                             cc = ct.narrow(ch, char());
3148 #endif /* BOOST_NO_STD_LOCALE */
3149 
3150                             if        (cc == '(')                            // read "(a,(("
3151                             {
3152                                 p = ::boost::math::quaternion<T>(a);
3153 
3154                                 is.putback(ch);
3155 
3156                                 is.putback(ch);                                // we backtrack twice, with the same value
3157 
3158                                 is >> q;                                    // read "(a,q"
3159 
3160                                 if    (!is.good())    goto finish;
3161 
3162                                 is >> ch;                                    // get the next lexeme
3163 
3164                                 if    (!is.good())    goto finish;
3165 
3166 #ifdef    BOOST_NO_STD_LOCALE
3167                                 cc = ch;
3168 #else
3169                                 cc = ct.narrow(ch, char());
3170 #endif /* BOOST_NO_STD_LOCALE */
3171 
3172                                 if        (cc == ')')                            // read "(a,q)"
3173                                 {
3174                                     o = octonion<T>(p,q);
3175                                 }
3176                                 else                                        // error
3177                                 {
3178                                     is.setstate(::std::ios_base::failbit);
3179                                 }
3180                             }
3181                             else                                        // read "(a,(c" or "(a,(e"
3182                             {
3183                                 is.putback(ch);
3184 
3185                                 is >> c;
3186 
3187                                 if    (!is.good())    goto finish;
3188 
3189                                 is >> ch;                                    // get the next lexeme
3190 
3191                                 if    (!is.good())    goto finish;
3192 
3193 #ifdef    BOOST_NO_STD_LOCALE
3194                                 cc = ch;
3195 #else
3196                                 cc = ct.narrow(ch, char());
3197 #endif /* BOOST_NO_STD_LOCALE */
3198 
3199                                 if        (cc == ')')                            // read "(a,(c)" (ambiguity resolution)
3200                                 {
3201                                     is >> ch;                                    // get the next lexeme
3202 
3203                                     if    (!is.good())    goto finish;
3204 
3205 #ifdef    BOOST_NO_STD_LOCALE
3206                                     cc = ch;
3207 #else
3208                                     cc = ct.narrow(ch, char());
3209 #endif /* BOOST_NO_STD_LOCALE */
3210 
3211                                     if        (cc == ')')                            // read "(a,(c))"
3212                                     {
3213                                         o = octonion<T>(a,b,c);
3214                                     }
3215                                     else if    (cc == ',')                            // read "(a,(c),"
3216                                     {
3217                                         u = ::std::complex<T>(a);
3218 
3219                                         v = ::std::complex<T>(c);
3220 
3221                                         is >> x;                                // read "(a,(c),x"
3222 
3223                                         if    (!is.good())    goto finish;
3224 
3225                                         is >> ch;                                    // get the next lexeme
3226 
3227                                         if    (!is.good())    goto finish;
3228 
3229 #ifdef    BOOST_NO_STD_LOCALE
3230                                         cc = ch;
3231 #else
3232                                         cc = ct.narrow(ch, char());
3233 #endif /* BOOST_NO_STD_LOCALE */
3234 
3235                                         if        (cc == ')')                            // read "(a,(c),x)"
3236                                         {
3237                                             o = octonion<T>(u,v,x);
3238                                         }
3239                                         else if    (cc == ',')                            // read "(a,(c),x,"
3240                                         {
3241                                             is >> y;                                    // read "(a,(c),x,y"
3242 
3243                                             if    (!is.good())    goto finish;
3244 
3245                                             is >> ch;                                    // get the next lexeme
3246 
3247                                             if    (!is.good())    goto finish;
3248 
3249 #ifdef    BOOST_NO_STD_LOCALE
3250                                             cc = ch;
3251 #else
3252                                             cc = ct.narrow(ch, char());
3253 #endif /* BOOST_NO_STD_LOCALE */
3254 
3255                                             if        (cc == ')')                            // read "(a,(c),x,y)"
3256                                             {
3257                                                 o = octonion<T>(u,v,x,y);
3258                                             }
3259                                             else                                        // error
3260                                             {
3261                                                 is.setstate(::std::ios_base::failbit);
3262                                             }
3263                                         }
3264                                         else                                        // error
3265                                         {
3266                                             is.setstate(::std::ios_base::failbit);
3267                                         }
3268                                     }
3269                                     else                                        // error
3270                                     {
3271                                         is.setstate(::std::ios_base::failbit);
3272                                     }
3273                                 }
3274                                 else if    (cc == ',')                            // read "(a,(c," or "(a,(e,"
3275                                 {
3276                                     is >> ch;                                    // get the next lexeme
3277 
3278                                     if    (!is.good())    goto finish;
3279 
3280 #ifdef    BOOST_NO_STD_LOCALE
3281                                     cc = ch;
3282 #else
3283                                     cc = ct.narrow(ch, char());
3284 #endif /* BOOST_NO_STD_LOCALE */
3285 
3286                                     if        (cc == '(')                            // read "(a,(e,(" (ambiguity resolution)
3287                                     {
3288                                         u = ::std::complex<T>(a);
3289 
3290                                         x = ::std::complex<T>(c);                // "c" is actually "e"
3291 
3292                                         is.putback(ch);                            // we backtrack
3293 
3294                                         is >> y;                                // read "(a,(e,y"
3295 
3296                                         if    (!is.good())    goto finish;
3297 
3298                                         is >> ch;                                    // get the next lexeme
3299 
3300                                         if    (!is.good())    goto finish;
3301 
3302 #ifdef    BOOST_NO_STD_LOCALE
3303                                         cc = ch;
3304 #else
3305                                         cc = ct.narrow(ch, char());
3306 #endif /* BOOST_NO_STD_LOCALE */
3307 
3308                                         if        (cc == ')')                            // read "(a,(e,y)"
3309                                         {
3310                                             is >> ch;                                    // get the next lexeme
3311 
3312                                             if    (!is.good())    goto finish;
3313 
3314 #ifdef    BOOST_NO_STD_LOCALE
3315                                             cc = ch;
3316 #else
3317                                             cc = ct.narrow(ch, char());
3318 #endif /* BOOST_NO_STD_LOCALE */
3319 
3320                                             if        (cc == ')')                            // read "(a,(e,y))"
3321                                             {
3322                                                 o = octonion<T>(u,v,x,y);
3323                                             }
3324                                             else                                        // error
3325                                             {
3326                                                 is.setstate(::std::ios_base::failbit);
3327                                             }
3328                                         }
3329                                         else                                        // error
3330                                         {
3331                                             is.setstate(::std::ios_base::failbit);
3332                                         }
3333                                     }
3334                                     else                                        // read "(a,(c,d" or "(a,(e,f"
3335                                     {
3336                                         is.putback(ch);
3337 
3338                                         is >> d;
3339 
3340                                         if    (!is.good())    goto finish;
3341 
3342                                         is >> ch;                                    // get the next lexeme
3343 
3344                                         if    (!is.good())    goto finish;
3345 
3346 #ifdef    BOOST_NO_STD_LOCALE
3347                                         cc = ch;
3348 #else
3349                                         cc = ct.narrow(ch, char());
3350 #endif /* BOOST_NO_STD_LOCALE */
3351 
3352                                         if        (cc == ')')                            // read "(a,(c,d)" (ambiguity resolution)
3353                                         {
3354                                             is >> ch;                                    // get the next lexeme
3355 
3356                                             if    (!is.good())    goto finish;
3357 
3358 #ifdef    BOOST_NO_STD_LOCALE
3359                                             cc = ch;
3360 #else
3361                                             cc = ct.narrow(ch, char());
3362 #endif /* BOOST_NO_STD_LOCALE */
3363 
3364                                             if        (cc == ')')                            // read "(a,(c,d))"
3365                                             {
3366                                                 o = octonion<T>(a,b,c,d);
3367                                             }
3368                                             else if    (cc == ',')                            // read "(a,(c,d),"
3369                                             {
3370                                                 u = ::std::complex<T>(a);
3371 
3372                                                 v = ::std::complex<T>(c,d);
3373 
3374                                                 is >> x;                                // read "(a,(c,d),x"
3375 
3376                                                 if    (!is.good())    goto finish;
3377 
3378                                                 is >> ch;                                    // get the next lexeme
3379 
3380                                                 if    (!is.good())    goto finish;
3381 
3382 #ifdef    BOOST_NO_STD_LOCALE
3383                                                 cc = ch;
3384 #else
3385                                                 cc = ct.narrow(ch, char());
3386 #endif /* BOOST_NO_STD_LOCALE */
3387 
3388                                                 if        (cc == ')')                            // read "(a,(c,d),x)"
3389                                                 {
3390                                                     o = octonion<T>(u,v,x);
3391                                                 }
3392                                                 else if    (cc == ',')                            // read "(a,(c,d),x,"
3393                                                 {
3394                                                     is >> y;                                    // read "(a,(c,d),x,y"
3395 
3396                                                     if    (!is.good())    goto finish;
3397 
3398                                                     is >> ch;                                    // get the next lexeme
3399 
3400                                                     if    (!is.good())    goto finish;
3401 
3402 #ifdef    BOOST_NO_STD_LOCALE
3403                                                     cc = ch;
3404 #else
3405                                                     cc = ct.narrow(ch, char());
3406 #endif /* BOOST_NO_STD_LOCALE */
3407 
3408                                                     if        (cc == ')')                            // read "(a,(c,d),x,y)"
3409                                                     {
3410                                                         o = octonion<T>(u,v,x,y);
3411                                                     }
3412                                                     else                                        // error
3413                                                     {
3414                                                         is.setstate(::std::ios_base::failbit);
3415                                                     }
3416                                                 }
3417                                                 else                                        // error
3418                                                 {
3419                                                     is.setstate(::std::ios_base::failbit);
3420                                                 }
3421                                             }
3422                                             else                                        // error
3423                                             {
3424                                                 is.setstate(::std::ios_base::failbit);
3425                                             }
3426                                         }
3427                                         else if    (cc == ',')                            // read "(a,(e,f," (ambiguity resolution)
3428                                         {
3429                                             p = ::boost::math::quaternion<T>(a);
3430 
3431                                             is >> g;                                    // read "(a,(e,f,g"
3432 
3433                                             if    (!is.good())    goto finish;
3434 
3435                                             is >> ch;                                    // get the next lexeme
3436 
3437                                             if    (!is.good())    goto finish;
3438 
3439 #ifdef    BOOST_NO_STD_LOCALE
3440                                             cc = ch;
3441 #else
3442                                             cc = ct.narrow(ch, char());
3443 #endif /* BOOST_NO_STD_LOCALE */
3444 
3445                                             if        (cc == ')')                            // read "(a,(e,f,g)"
3446                                             {
3447                                                 is >> ch;                                    // get the next lexeme
3448 
3449                                                 if    (!is.good())    goto finish;
3450 
3451 #ifdef    BOOST_NO_STD_LOCALE
3452                                                 cc = ch;
3453 #else
3454                                                 cc = ct.narrow(ch, char());
3455 #endif /* BOOST_NO_STD_LOCALE */
3456 
3457                                                 if        (cc == ')')                            // read "(a,(e,f,g))"
3458                                                 {
3459                                                     q = ::boost::math::quaternion<T>(c,d,g);            // "c" is actually "e" and "d" is actually "f"
3460 
3461                                                     o = octonion<T>(p,q);
3462                                                 }
3463                                                 else                                        // error
3464                                                 {
3465                                                     is.setstate(::std::ios_base::failbit);
3466                                                 }
3467                                             }
3468                                             else if    (cc == ',')                            // read "(a,(e,f,g,"
3469                                             {
3470                                                 is >> h;                                    // read "(a,(e,f,g,h"
3471 
3472                                                 if    (!is.good())    goto finish;
3473 
3474                                                 is >> ch;                                    // get the next lexeme
3475 
3476                                                 if    (!is.good())    goto finish;
3477 
3478 #ifdef    BOOST_NO_STD_LOCALE
3479                                                 cc = ch;
3480 #else
3481                                                 cc = ct.narrow(ch, char());
3482 #endif /* BOOST_NO_STD_LOCALE */
3483 
3484                                                 if        (cc == ')')                            // read "(a,(e,f,g,h)"
3485                                                 {
3486                                                     is >> ch;                                    // get the next lexeme
3487 
3488                                                     if    (!is.good())    goto finish;
3489 
3490 #ifdef    BOOST_NO_STD_LOCALE
3491                                                     cc = ch;
3492 #else
3493                                                     cc = ct.narrow(ch, char());
3494 #endif /* BOOST_NO_STD_LOCALE */
3495 
3496                                                     if        (cc == ')')                            // read "(a,(e,f,g,h))"
3497                                                     {
3498                                                         q = ::boost::math::quaternion<T>(c,d,g,h);            // "c" is actually "e" and "d" is actually "f"
3499 
3500                                                         o = octonion<T>(p,q);
3501                                                     }
3502                                                     else                                        // error
3503                                                     {
3504                                                         is.setstate(::std::ios_base::failbit);
3505                                                     }
3506                                                 }
3507                                                 else                                        // error
3508                                                 {
3509                                                     is.setstate(::std::ios_base::failbit);
3510                                                 }
3511                                             }
3512                                             else                                        // error
3513                                             {
3514                                                 is.setstate(::std::ios_base::failbit);
3515                                             }
3516                                         }
3517                                         else                                        // error
3518                                         {
3519                                             is.setstate(::std::ios_base::failbit);
3520                                         }
3521                                     }
3522                                 }
3523                                 else                                        // error
3524                                 {
3525                                     is.setstate(::std::ios_base::failbit);
3526                                 }
3527                             }
3528                         }
3529                         else                                        // read "(a,b" or "(a,c" (ambiguity resolution)
3530                         {
3531                             is.putback(ch);
3532 
3533                             is >> b;
3534 
3535                             if    (!is.good())    goto finish;
3536 
3537                             is >> ch;                                    // get the next lexeme
3538 
3539                             if    (!is.good())    goto finish;
3540 
3541 #ifdef    BOOST_NO_STD_LOCALE
3542                             cc = ch;
3543 #else
3544                             cc = ct.narrow(ch, char());
3545 #endif /* BOOST_NO_STD_LOCALE */
3546 
3547                             if        (cc == ')')                            // read "(a,b)" (ambiguity resolution)
3548                             {
3549                                 o = octonion<T>(a,b);
3550                             }
3551                             else if    (cc == ',')                            // read "(a,b," or "(a,c,"
3552                             {
3553                                 is >> ch;                                    // get the next lexeme
3554 
3555                                 if    (!is.good())    goto finish;
3556 
3557 #ifdef    BOOST_NO_STD_LOCALE
3558                                 cc = ch;
3559 #else
3560                                 cc = ct.narrow(ch, char());
3561 #endif /* BOOST_NO_STD_LOCALE */
3562 
3563                                 if        (cc == '(')                            // read "(a,c,(" (ambiguity resolution)
3564                                 {
3565                                     u = ::std::complex<T>(a);
3566 
3567                                     v = ::std::complex<T>(b);                    // "b" is actually "c"
3568 
3569                                     is.putback(ch);                                // we backtrack
3570 
3571                                     is >> x;                                    // read "(a,c,x"
3572 
3573                                     if    (!is.good())    goto finish;
3574 
3575                                     is >> ch;                                    // get the next lexeme
3576 
3577                                     if    (!is.good())    goto finish;
3578 
3579 #ifdef    BOOST_NO_STD_LOCALE
3580                                     cc = ch;
3581 #else
3582                                     cc = ct.narrow(ch, char());
3583 #endif /* BOOST_NO_STD_LOCALE */
3584 
3585                                     if        (cc == ')')                            // read "(a,c,x)"
3586                                     {
3587                                         o = octonion<T>(u,v,x);
3588                                     }
3589                                     else if    (cc == ',')                            // read "(a,c,x,"
3590                                     {
3591                                         is >> y;                                    // read "(a,c,x,y"                                    // read "(a,c,x"
3592 
3593                                         if    (!is.good())    goto finish;
3594 
3595                                         is >> ch;                                    // get the next lexeme
3596 
3597                                         if    (!is.good())    goto finish;
3598 
3599 #ifdef    BOOST_NO_STD_LOCALE
3600                                         cc = ch;
3601 #else
3602                                         cc = ct.narrow(ch, char());
3603 #endif /* BOOST_NO_STD_LOCALE */
3604 
3605                                         if        (cc == ')')                            // read "(a,c,x,y)"
3606                                         {
3607                                             o = octonion<T>(u,v,x,y);
3608                                         }
3609                                         else                                        // error
3610                                         {
3611                                             is.setstate(::std::ios_base::failbit);
3612                                         }
3613                                     }
3614                                     else                                        // error
3615                                     {
3616                                         is.setstate(::std::ios_base::failbit);
3617                                     }
3618                                 }
3619                                 else                                        // read "(a,b,c" or "(a,c,e"
3620                                 {
3621                                     is.putback(ch);
3622 
3623                                     is >> c;
3624 
3625                                     if    (!is.good())    goto finish;
3626 
3627                                     is >> ch;                                    // get the next lexeme
3628 
3629                                     if    (!is.good())    goto finish;
3630 
3631 #ifdef    BOOST_NO_STD_LOCALE
3632                                     cc = ch;
3633 #else
3634                                     cc = ct.narrow(ch, char());
3635 #endif /* BOOST_NO_STD_LOCALE */
3636 
3637                                     if        (cc == ')')                            // read "(a,b,c)" (ambiguity resolution)
3638                                     {
3639                                         o = octonion<T>(a,b,c);
3640                                     }
3641                                     else if    (cc == ',')                            // read "(a,b,c," or "(a,c,e,"
3642                                     {
3643                                         is >> ch;                                    // get the next lexeme
3644 
3645                                         if    (!is.good())    goto finish;
3646 
3647 #ifdef    BOOST_NO_STD_LOCALE
3648                                         cc = ch;
3649 #else
3650                                         cc = ct.narrow(ch, char());
3651 #endif /* BOOST_NO_STD_LOCALE */
3652 
3653                                         if        (cc == '(')                            // read "(a,c,e,(") (ambiguity resolution)
3654                                         {
3655                                             u = ::std::complex<T>(a);
3656 
3657                                             v = ::std::complex<T>(b);                    // "b" is actually "c"
3658 
3659                                             x = ::std::complex<T>(c);                    // "c" is actually "e"
3660 
3661                                             is.putback(ch);                                // we backtrack
3662 
3663                                             is >> y;                                    // read "(a,c,e,y"
3664 
3665                                             if    (!is.good())    goto finish;
3666 
3667                                             is >> ch;                                    // get the next lexeme
3668 
3669                                             if    (!is.good())    goto finish;
3670 
3671 #ifdef    BOOST_NO_STD_LOCALE
3672                                             cc = ch;
3673 #else
3674                                             cc = ct.narrow(ch, char());
3675 #endif /* BOOST_NO_STD_LOCALE */
3676 
3677                                             if        (cc == ')')                            // read "(a,c,e,y)"
3678                                             {
3679                                                 o = octonion<T>(u,v,x,y);
3680                                             }
3681                                             else                                        // error
3682                                             {
3683                                                 is.setstate(::std::ios_base::failbit);
3684                                             }
3685                                         }
3686                                         else                                        // read "(a,b,c,d" (ambiguity resolution)
3687                                         {
3688                                             is.putback(ch);                                // we backtrack
3689 
3690                                             is >> d;
3691 
3692                                             if    (!is.good())    goto finish;
3693 
3694                                             is >> ch;                                    // get the next lexeme
3695 
3696                                             if    (!is.good())    goto finish;
3697 
3698 #ifdef    BOOST_NO_STD_LOCALE
3699                                             cc = ch;
3700 #else
3701                                             cc = ct.narrow(ch, char());
3702 #endif /* BOOST_NO_STD_LOCALE */
3703 
3704                                             if        (cc == ')')                            // read "(a,b,c,d)"
3705                                             {
3706                                                 o = octonion<T>(a,b,c,d);
3707                                             }
3708                                             else if    (cc == ',')                            // read "(a,b,c,d,"
3709                                             {
3710                                                 is >> e;                                    // read "(a,b,c,d,e"
3711 
3712                                                 if    (!is.good())    goto finish;
3713 
3714                                                 is >> ch;                                    // get the next lexeme
3715 
3716                                                 if    (!is.good())    goto finish;
3717 
3718 #ifdef    BOOST_NO_STD_LOCALE
3719                                                 cc = ch;
3720 #else
3721                                                 cc = ct.narrow(ch, char());
3722 #endif /* BOOST_NO_STD_LOCALE */
3723 
3724                                                 if        (cc == ')')                            // read "(a,b,c,d,e)"
3725                                                 {
3726                                                     o = octonion<T>(a,b,c,d,e);
3727                                                 }
3728                                                 else if    (cc == ',')                            // read "(a,b,c,d,e,"
3729                                                 {
3730                                                     is >> f;                                    // read "(a,b,c,d,e,f"
3731 
3732                                                     if    (!is.good())    goto finish;
3733 
3734                                                     is >> ch;                                    // get the next lexeme
3735 
3736                                                     if    (!is.good())    goto finish;
3737 
3738 #ifdef    BOOST_NO_STD_LOCALE
3739                                                     cc = ch;
3740 #else
3741                                                     cc = ct.narrow(ch, char());
3742 #endif /* BOOST_NO_STD_LOCALE */
3743 
3744                                                     if        (cc == ')')                            // read "(a,b,c,d,e,f)"
3745                                                     {
3746                                                         o = octonion<T>(a,b,c,d,e,f);
3747                                                     }
3748                                                     else if    (cc == ',')                            // read "(a,b,c,d,e,f,"
3749                                                     {
3750                                                         is >> g;                                    // read "(a,b,c,d,e,f,g"                                    // read "(a,b,c,d,e,f"
3751 
3752                                                         if    (!is.good())    goto finish;
3753 
3754                                                         is >> ch;                                    // get the next lexeme
3755 
3756                                                         if    (!is.good())    goto finish;
3757 
3758 #ifdef    BOOST_NO_STD_LOCALE
3759                                                         cc = ch;
3760 #else
3761                                                         cc = ct.narrow(ch, char());
3762 #endif /* BOOST_NO_STD_LOCALE */
3763 
3764                                                         if        (cc == ')')                            // read "(a,b,c,d,e,f,g)"
3765                                                         {
3766                                                             o = octonion<T>(a,b,c,d,e,f,g);
3767                                                         }
3768                                                         else if    (cc == ',')                            // read "(a,b,c,d,e,f,g,"
3769                                                         {
3770                                                             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"
3771 
3772                                                             if    (!is.good())    goto finish;
3773 
3774                                                             is >> ch;                                    // get the next lexeme
3775 
3776                                                             if    (!is.good())    goto finish;
3777 
3778 #ifdef    BOOST_NO_STD_LOCALE
3779                                                             cc = ch;
3780 #else
3781                                                             cc = ct.narrow(ch, char());
3782 #endif /* BOOST_NO_STD_LOCALE */
3783 
3784                                                             if        (cc == ')')                            // read "(a,b,c,d,e,f,g,h)"
3785                                                             {
3786                                                                 o = octonion<T>(a,b,c,d,e,f,g,h);
3787                                                             }
3788                                                             else                                        // error
3789                                                             {
3790                                                                 is.setstate(::std::ios_base::failbit);
3791                                                             }
3792                                                         }
3793                                                         else                                        // error
3794                                                         {
3795                                                             is.setstate(::std::ios_base::failbit);
3796                                                         }
3797                                                     }
3798                                                     else                                        // error
3799                                                     {
3800                                                         is.setstate(::std::ios_base::failbit);
3801                                                     }
3802                                                 }
3803                                                 else                                        // error
3804                                                 {
3805                                                     is.setstate(::std::ios_base::failbit);
3806                                                 }
3807                                             }
3808                                             else                                        // error
3809                                             {
3810                                                 is.setstate(::std::ios_base::failbit);
3811                                             }
3812                                         }
3813                                     }
3814                                     else                                        // error
3815                                     {
3816                                         is.setstate(::std::ios_base::failbit);
3817                                     }
3818                                 }
3819                             }
3820                             else                                        // error
3821                             {
3822                                 is.setstate(::std::ios_base::failbit);
3823                             }
3824                         }
3825                     }
3826                     else                                        // error
3827                     {
3828                         is.setstate(::std::ios_base::failbit);
3829                     }
3830                 }
3831             }
3832             else                                        // format:    a
3833             {
3834                 is.putback(ch);
3835 
3836                 is >> a;                                    // we extract the first component
3837 
3838                 if    (!is.good())    goto finish;
3839 
3840                 o = octonion<T>(a);
3841             }
3842 
3843             finish:
3844             return(is);
3845         }
3846 
3847 
3848         template<typename T, typename charT, class traits>
3849         ::std::basic_ostream<charT,traits> &    operator << (    ::std::basic_ostream<charT,traits> & os,
3850                                                                 octonion<T> const & o)
3851         {
3852             ::std::basic_ostringstream<charT,traits>    s;
3853 
3854             s.flags(os.flags());
3855 #ifdef    BOOST_NO_STD_LOCALE
3856 #else
3857             s.imbue(os.getloc());
3858 #endif /* BOOST_NO_STD_LOCALE */
3859             s.precision(os.precision());
3860 
3861             s << '('    << o.R_component_1() << ','
3862                         << o.R_component_2() << ','
3863                         << o.R_component_3() << ','
3864                         << o.R_component_4() << ','
3865                         << o.R_component_5() << ','
3866                         << o.R_component_6() << ','
3867                         << o.R_component_7() << ','
3868                         << o.R_component_8() << ')';
3869 
3870             return os << s.str();
3871         }
3872 
3873 
3874         // values
3875 
3876         template<typename T>
3877         inline T                                real(octonion<T> const & o)
3878         {
3879             return(o.real());
3880         }
3881 
3882 
3883         template<typename T>
3884         inline octonion<T>                        unreal(octonion<T> const & o)
3885         {
3886             return(o.unreal());
3887         }
3888 
3889 
3890 #define    BOOST_OCTONION_VALARRAY_LOADER   \
3891             using    ::std::valarray;       \
3892                                             \
3893             valarray<T>    temp(8);         \
3894                                             \
3895             temp[0] = o.R_component_1();    \
3896             temp[1] = o.R_component_2();    \
3897             temp[2] = o.R_component_3();    \
3898             temp[3] = o.R_component_4();    \
3899             temp[4] = o.R_component_5();    \
3900             temp[5] = o.R_component_6();    \
3901             temp[6] = o.R_component_7();    \
3902             temp[7] = o.R_component_8();
3903 
3904 
3905         template<typename T>
3906         inline T                                sup(octonion<T> const & o)
3907         {
3908 #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
3909             using    ::std::abs;
3910 #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
3911 
3912             BOOST_OCTONION_VALARRAY_LOADER
3913 
3914             return((abs(temp).max)());
3915         }
3916 
3917 
3918         template<typename T>
3919         inline T                                l1(octonion<T> const & o)
3920         {
3921 #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
3922             using    ::std::abs;
3923 #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
3924 
3925             BOOST_OCTONION_VALARRAY_LOADER
3926 
3927             return(abs(temp).sum());
3928         }
3929 
3930 
3931         template<typename T>
3932         inline T                                abs(const octonion<T> & o)
3933         {
3934 #ifdef    BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
3935             using    ::std::abs;
3936 #endif    /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */
3937 
3938             using    ::std::sqrt;
3939 
3940             BOOST_OCTONION_VALARRAY_LOADER
3941 
3942             T            maxim = (abs(temp).max)();    // overflow protection
3943 
3944             if    (maxim == static_cast<T>(0))
3945             {
3946                 return(maxim);
3947             }
3948             else
3949             {
3950                 T    mixam = static_cast<T>(1)/maxim;    // prefer multiplications over divisions
3951 
3952                 temp *= mixam;
3953 
3954                 temp *= temp;
3955 
3956                 return(maxim*sqrt(temp.sum()));
3957             }
3958 
3959             //return(::std::sqrt(norm(o)));
3960         }
3961 
3962 
3963 #undef    BOOST_OCTONION_VALARRAY_LOADER
3964 
3965 
3966         // Note:    This is the Cayley norm, not the Euclidean norm...
3967 
3968         template<typename T>
3969         inline T                                norm(octonion<T> const & o)
3970         {
3971             return(real(o*conj(o)));
3972         }
3973 
3974 
3975         template<typename T>
3976         inline octonion<T>                        conj(octonion<T> const & o)
3977         {
3978             return(octonion<T>( +o.R_component_1(),
3979                                 -o.R_component_2(),
3980                                 -o.R_component_3(),
3981                                 -o.R_component_4(),
3982                                 -o.R_component_5(),
3983                                 -o.R_component_6(),
3984                                 -o.R_component_7(),
3985                                 -o.R_component_8()));
3986         }
3987 
3988 
3989         // Note:    There is little point, for the octonions, to introduce the equivalents
3990         //            to the complex "arg" and the quaternionic "cylindropolar".
3991 
3992 
3993         template<typename T>
3994         inline octonion<T>                        spherical(T const & rho,
3995                                                             T const & theta,
3996                                                             T const & phi1,
3997                                                             T const & phi2,
3998                                                             T const & phi3,
3999                                                             T const & phi4,
4000                                                             T const & phi5,
4001                                                             T const & phi6)
4002         {
4003             using ::std::cos;
4004             using ::std::sin;
4005 
4006             //T    a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4007             //T    b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4008             //T    c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4009             //T    d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4010             //T    e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6);
4011             //T    f = sin(phi4)*cos(phi5)*cos(phi6);
4012             //T    g = sin(phi5)*cos(phi6);
4013             //T    h = sin(phi6);
4014 
4015             T    courrant = static_cast<T>(1);
4016 
4017             T    h = sin(phi6);
4018 
4019             courrant *= cos(phi6);
4020 
4021             T    g = sin(phi5)*courrant;
4022 
4023             courrant *= cos(phi5);
4024 
4025             T    f = sin(phi4)*courrant;
4026 
4027             courrant *= cos(phi4);
4028 
4029             T    e = sin(phi3)*courrant;
4030 
4031             courrant *= cos(phi3);
4032 
4033             T    d = sin(phi2)*courrant;
4034 
4035             courrant *= cos(phi2);
4036 
4037             T    c = sin(phi1)*courrant;
4038 
4039             courrant *= cos(phi1);
4040 
4041             T    b = sin(theta)*courrant;
4042             T    a = cos(theta)*courrant;
4043 
4044             return(rho*octonion<T>(a,b,c,d,e,f,g,h));
4045         }
4046 
4047 
4048         template<typename T>
4049         inline octonion<T>                        multipolar(T const & rho1,
4050                                                              T const & theta1,
4051                                                              T const & rho2,
4052                                                              T const & theta2,
4053                                                              T const & rho3,
4054                                                              T const & theta3,
4055                                                              T const & rho4,
4056                                                              T const & theta4)
4057         {
4058             using ::std::cos;
4059             using ::std::sin;
4060 
4061             T    a = rho1*cos(theta1);
4062             T    b = rho1*sin(theta1);
4063             T    c = rho2*cos(theta2);
4064             T    d = rho2*sin(theta2);
4065             T    e = rho3*cos(theta3);
4066             T    f = rho3*sin(theta3);
4067             T    g = rho4*cos(theta4);
4068             T    h = rho4*sin(theta4);
4069 
4070             return(octonion<T>(a,b,c,d,e,f,g,h));
4071         }
4072 
4073 
4074         template<typename T>
4075         inline octonion<T>                        cylindrical(T const & r,
4076                                                               T const & angle,
4077                                                               T const & h1,
4078                                                               T const & h2,
4079                                                               T const & h3,
4080                                                               T const & h4,
4081                                                               T const & h5,
4082                                                               T const & h6)
4083         {
4084             using ::std::cos;
4085             using ::std::sin;
4086 
4087             T    a = r*cos(angle);
4088             T    b = r*sin(angle);
4089 
4090             return(octonion<T>(a,b,h1,h2,h3,h4,h5,h6));
4091         }
4092 
4093 
4094         template<typename T>
4095         inline octonion<T>                        exp(octonion<T> const & o)
4096         {
4097             using    ::std::exp;
4098             using    ::std::cos;
4099 
4100             using    ::boost::math::sinc_pi;
4101 
4102             T    u = exp(real(o));
4103 
4104             T    z = abs(unreal(o));
4105 
4106             T    w = sinc_pi(z);
4107 
4108             return(u*octonion<T>(cos(z),
4109                 w*o.R_component_2(), w*o.R_component_3(),
4110                 w*o.R_component_4(), w*o.R_component_5(),
4111                 w*o.R_component_6(), w*o.R_component_7(),
4112                 w*o.R_component_8()));
4113         }
4114 
4115 
4116         template<typename T>
4117         inline octonion<T>                        cos(octonion<T> const & o)
4118         {
4119             using    ::std::sin;
4120             using    ::std::cos;
4121             using    ::std::cosh;
4122 
4123             using    ::boost::math::sinhc_pi;
4124 
4125             T    z = abs(unreal(o));
4126 
4127             T    w = -sin(o.real())*sinhc_pi(z);
4128 
4129             return(octonion<T>(cos(o.real())*cosh(z),
4130                 w*o.R_component_2(), w*o.R_component_3(),
4131                 w*o.R_component_4(), w*o.R_component_5(),
4132                 w*o.R_component_6(), w*o.R_component_7(),
4133                 w*o.R_component_8()));
4134         }
4135 
4136 
4137         template<typename T>
4138         inline octonion<T>                        sin(octonion<T> const & o)
4139         {
4140             using    ::std::sin;
4141             using    ::std::cos;
4142             using    ::std::cosh;
4143 
4144             using    ::boost::math::sinhc_pi;
4145 
4146             T    z = abs(unreal(o));
4147 
4148             T    w = +cos(o.real())*sinhc_pi(z);
4149 
4150             return(octonion<T>(sin(o.real())*cosh(z),
4151                 w*o.R_component_2(), w*o.R_component_3(),
4152                 w*o.R_component_4(), w*o.R_component_5(),
4153                 w*o.R_component_6(), w*o.R_component_7(),
4154                 w*o.R_component_8()));
4155         }
4156 
4157 
4158         template<typename T>
4159         inline octonion<T>                        tan(octonion<T> const & o)
4160         {
4161             return(sin(o)/cos(o));
4162         }
4163 
4164 
4165         template<typename T>
4166         inline octonion<T>                        cosh(octonion<T> const & o)
4167         {
4168             return((exp(+o)+exp(-o))/static_cast<T>(2));
4169         }
4170 
4171 
4172         template<typename T>
4173         inline octonion<T>                        sinh(octonion<T> const & o)
4174         {
4175             return((exp(+o)-exp(-o))/static_cast<T>(2));
4176         }
4177 
4178 
4179         template<typename T>
4180         inline octonion<T>                        tanh(octonion<T> const & o)
4181         {
4182             return(sinh(o)/cosh(o));
4183         }
4184 
4185 
4186         template<typename T>
4187         octonion<T>                                pow(octonion<T> const & o,
4188                                                     int n)
4189         {
4190             if        (n > 1)
4191             {
4192                 int    m = n>>1;
4193 
4194                 octonion<T>    result = pow(o, m);
4195 
4196                 result *= result;
4197 
4198                 if    (n != (m<<1))
4199                 {
4200                     result *= o; // n odd
4201                 }
4202 
4203                 return(result);
4204             }
4205             else if    (n == 1)
4206             {
4207                 return(o);
4208             }
4209             else if    (n == 0)
4210             {
4211                 return(octonion<T>(static_cast<T>(1)));
4212             }
4213             else    /* n < 0 */
4214             {
4215                 return(pow(octonion<T>(static_cast<T>(1))/o,-n));
4216             }
4217         }
4218 
4219 
4220         // helper templates for converting copy constructors (definition)
4221 
4222         namespace detail
4223         {
4224 
4225             template<   typename T,
4226                         typename U
4227                     >
4228             octonion<T>    octonion_type_converter(octonion<U> const & rhs)
4229             {
4230                 return(octonion<T>( static_cast<T>(rhs.R_component_1()),
4231                                     static_cast<T>(rhs.R_component_2()),
4232                                     static_cast<T>(rhs.R_component_3()),
4233                                     static_cast<T>(rhs.R_component_4()),
4234                                     static_cast<T>(rhs.R_component_5()),
4235                                     static_cast<T>(rhs.R_component_6()),
4236                                     static_cast<T>(rhs.R_component_7()),
4237                                     static_cast<T>(rhs.R_component_8())));
4238             }
4239         }
4240     }
4241 }
4242 
4243 #endif /* BOOST_OCTONION_HPP */