Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/math/octonion.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // boost octonion.hpp header file | |
2 | |
3 // (C) Copyright Hubert Holin 2001. | |
4 // Distributed under the Boost Software License, Version 1.0. (See | |
5 // accompanying file LICENSE_1_0.txt or copy at | |
6 // http://www.boost.org/LICENSE_1_0.txt) | |
7 | |
8 // See http://www.boost.org for updates, documentation, and revision history. | |
9 | |
10 | |
11 #ifndef BOOST_OCTONION_HPP | |
12 #define BOOST_OCTONION_HPP | |
13 | |
14 #include <boost/math/quaternion.hpp> | |
15 | |
16 | |
17 namespace boost | |
18 { | |
19 namespace math | |
20 { | |
21 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
22 // gcc 2.95.x uses expression templates for valarray calculations, but | |
23 // the result is not conforming. We need BOOST_GET_VALARRAY to get an | |
24 // actual valarray result when we need to call a member function | |
25 #define BOOST_GET_VALARRAY(T,x) ::std::valarray<T>(x) | |
26 // gcc 2.95.x has an "std::ios" class that is similar to | |
27 // "std::ios_base", so we just use a #define | |
28 #define BOOST_IOS_BASE ::std::ios | |
29 // gcc 2.x ignores function scope using declarations, | |
30 // put them in the scope of the enclosing namespace instead: | |
31 using ::std::valarray; | |
32 using ::std::sqrt; | |
33 using ::std::cos; | |
34 using ::std::sin; | |
35 using ::std::exp; | |
36 using ::std::cosh; | |
37 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
38 | |
39 #define BOOST_OCTONION_ACCESSOR_GENERATOR(type) \ | |
40 type real() const \ | |
41 { \ | |
42 return(a); \ | |
43 } \ | |
44 \ | |
45 octonion<type> unreal() const \ | |
46 { \ | |
47 return( octonion<type>(static_cast<type>(0),b,c,d,e,f,g,h)); \ | |
48 } \ | |
49 \ | |
50 type R_component_1() const \ | |
51 { \ | |
52 return(a); \ | |
53 } \ | |
54 \ | |
55 type R_component_2() const \ | |
56 { \ | |
57 return(b); \ | |
58 } \ | |
59 \ | |
60 type R_component_3() const \ | |
61 { \ | |
62 return(c); \ | |
63 } \ | |
64 \ | |
65 type R_component_4() const \ | |
66 { \ | |
67 return(d); \ | |
68 } \ | |
69 \ | |
70 type R_component_5() const \ | |
71 { \ | |
72 return(e); \ | |
73 } \ | |
74 \ | |
75 type R_component_6() const \ | |
76 { \ | |
77 return(f); \ | |
78 } \ | |
79 \ | |
80 type R_component_7() const \ | |
81 { \ | |
82 return(g); \ | |
83 } \ | |
84 \ | |
85 type R_component_8() const \ | |
86 { \ | |
87 return(h); \ | |
88 } \ | |
89 \ | |
90 ::std::complex<type> C_component_1() const \ | |
91 { \ | |
92 return(::std::complex<type>(a,b)); \ | |
93 } \ | |
94 \ | |
95 ::std::complex<type> C_component_2() const \ | |
96 { \ | |
97 return(::std::complex<type>(c,d)); \ | |
98 } \ | |
99 \ | |
100 ::std::complex<type> C_component_3() const \ | |
101 { \ | |
102 return(::std::complex<type>(e,f)); \ | |
103 } \ | |
104 \ | |
105 ::std::complex<type> C_component_4() const \ | |
106 { \ | |
107 return(::std::complex<type>(g,h)); \ | |
108 } \ | |
109 \ | |
110 ::boost::math::quaternion<type> H_component_1() const \ | |
111 { \ | |
112 return(::boost::math::quaternion<type>(a,b,c,d)); \ | |
113 } \ | |
114 \ | |
115 ::boost::math::quaternion<type> H_component_2() const \ | |
116 { \ | |
117 return(::boost::math::quaternion<type>(e,f,g,h)); \ | |
118 } | |
119 | |
120 | |
121 #define BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type) \ | |
122 template<typename X> \ | |
123 octonion<type> & operator = (octonion<X> const & a_affecter) \ | |
124 { \ | |
125 a = static_cast<type>(a_affecter.R_component_1()); \ | |
126 b = static_cast<type>(a_affecter.R_component_2()); \ | |
127 c = static_cast<type>(a_affecter.R_component_3()); \ | |
128 d = static_cast<type>(a_affecter.R_component_4()); \ | |
129 e = static_cast<type>(a_affecter.R_component_5()); \ | |
130 f = static_cast<type>(a_affecter.R_component_6()); \ | |
131 g = static_cast<type>(a_affecter.R_component_7()); \ | |
132 h = static_cast<type>(a_affecter.R_component_8()); \ | |
133 \ | |
134 return(*this); \ | |
135 } \ | |
136 \ | |
137 octonion<type> & operator = (octonion<type> const & a_affecter) \ | |
138 { \ | |
139 a = a_affecter.a; \ | |
140 b = a_affecter.b; \ | |
141 c = a_affecter.c; \ | |
142 d = a_affecter.d; \ | |
143 e = a_affecter.e; \ | |
144 f = a_affecter.f; \ | |
145 g = a_affecter.g; \ | |
146 h = a_affecter.h; \ | |
147 \ | |
148 return(*this); \ | |
149 } \ | |
150 \ | |
151 octonion<type> & operator = (type const & a_affecter) \ | |
152 { \ | |
153 a = a_affecter; \ | |
154 \ | |
155 b = c = d = e = f= g = h = static_cast<type>(0); \ | |
156 \ | |
157 return(*this); \ | |
158 } \ | |
159 \ | |
160 octonion<type> & operator = (::std::complex<type> const & a_affecter) \ | |
161 { \ | |
162 a = a_affecter.real(); \ | |
163 b = a_affecter.imag(); \ | |
164 \ | |
165 c = d = e = f = g = h = static_cast<type>(0); \ | |
166 \ | |
167 return(*this); \ | |
168 } \ | |
169 \ | |
170 octonion<type> & operator = (::boost::math::quaternion<type> const & a_affecter) \ | |
171 { \ | |
172 a = a_affecter.R_component_1(); \ | |
173 b = a_affecter.R_component_2(); \ | |
174 c = a_affecter.R_component_3(); \ | |
175 d = a_affecter.R_component_4(); \ | |
176 \ | |
177 e = f = g = h = static_cast<type>(0); \ | |
178 \ | |
179 return(*this); \ | |
180 } | |
181 | |
182 | |
183 #define BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \ | |
184 type a; \ | |
185 type b; \ | |
186 type c; \ | |
187 type d; \ | |
188 type e; \ | |
189 type f; \ | |
190 type g; \ | |
191 type h; \ | |
192 | |
193 | |
194 template<typename T> | |
195 class octonion | |
196 { | |
197 public: | |
198 | |
199 typedef T value_type; | |
200 | |
201 // constructor for O seen as R^8 | |
202 // (also default constructor) | |
203 | |
204 explicit octonion( T const & requested_a = T(), | |
205 T const & requested_b = T(), | |
206 T const & requested_c = T(), | |
207 T const & requested_d = T(), | |
208 T const & requested_e = T(), | |
209 T const & requested_f = T(), | |
210 T const & requested_g = T(), | |
211 T const & requested_h = T()) | |
212 : a(requested_a), | |
213 b(requested_b), | |
214 c(requested_c), | |
215 d(requested_d), | |
216 e(requested_e), | |
217 f(requested_f), | |
218 g(requested_g), | |
219 h(requested_h) | |
220 { | |
221 // nothing to do! | |
222 } | |
223 | |
224 | |
225 // constructor for H seen as C^4 | |
226 | |
227 explicit octonion( ::std::complex<T> const & z0, | |
228 ::std::complex<T> const & z1 = ::std::complex<T>(), | |
229 ::std::complex<T> const & z2 = ::std::complex<T>(), | |
230 ::std::complex<T> const & z3 = ::std::complex<T>()) | |
231 : a(z0.real()), | |
232 b(z0.imag()), | |
233 c(z1.real()), | |
234 d(z1.imag()), | |
235 e(z2.real()), | |
236 f(z2.imag()), | |
237 g(z3.real()), | |
238 h(z3.imag()) | |
239 { | |
240 // nothing to do! | |
241 } | |
242 | |
243 | |
244 // constructor for O seen as H^2 | |
245 | |
246 explicit octonion( ::boost::math::quaternion<T> const & q0, | |
247 ::boost::math::quaternion<T> const & q1 = ::boost::math::quaternion<T>()) | |
248 : a(q0.R_component_1()), | |
249 b(q0.R_component_2()), | |
250 c(q0.R_component_3()), | |
251 d(q0.R_component_4()), | |
252 e(q1.R_component_1()), | |
253 f(q1.R_component_2()), | |
254 g(q1.R_component_3()), | |
255 h(q1.R_component_4()) | |
256 { | |
257 // nothing to do! | |
258 } | |
259 | |
260 | |
261 // UNtemplated copy constructor | |
262 // (this is taken care of by the compiler itself) | |
263 | |
264 | |
265 // templated copy constructor | |
266 | |
267 template<typename X> | |
268 explicit octonion(octonion<X> const & a_recopier) | |
269 : a(static_cast<T>(a_recopier.R_component_1())), | |
270 b(static_cast<T>(a_recopier.R_component_2())), | |
271 c(static_cast<T>(a_recopier.R_component_3())), | |
272 d(static_cast<T>(a_recopier.R_component_4())), | |
273 e(static_cast<T>(a_recopier.R_component_5())), | |
274 f(static_cast<T>(a_recopier.R_component_6())), | |
275 g(static_cast<T>(a_recopier.R_component_7())), | |
276 h(static_cast<T>(a_recopier.R_component_8())) | |
277 { | |
278 // nothing to do! | |
279 } | |
280 | |
281 | |
282 // destructor | |
283 // (this is taken care of by the compiler itself) | |
284 | |
285 | |
286 // accessors | |
287 // | |
288 // Note: Like complex number, octonions do have a meaningful notion of "real part", | |
289 // but unlike them there is no meaningful notion of "imaginary part". | |
290 // Instead there is an "unreal part" which itself is an octonion, and usually | |
291 // nothing simpler (as opposed to the complex number case). | |
292 // However, for practicallity, there are accessors for the other components | |
293 // (these are necessary for the templated copy constructor, for instance). | |
294 | |
295 BOOST_OCTONION_ACCESSOR_GENERATOR(T) | |
296 | |
297 // assignment operators | |
298 | |
299 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T) | |
300 | |
301 // other assignment-related operators | |
302 // | |
303 // NOTE: Octonion multiplication is *NOT* commutative; | |
304 // symbolically, "q *= rhs;" means "q = q * rhs;" | |
305 // and "q /= rhs;" means "q = q * inverse_of(rhs);"; | |
306 // octonion multiplication is also *NOT* associative | |
307 | |
308 octonion<T> & operator += (T const & rhs) | |
309 { | |
310 T at = a + rhs; // exception guard | |
311 | |
312 a = at; | |
313 | |
314 return(*this); | |
315 } | |
316 | |
317 | |
318 octonion<T> & operator += (::std::complex<T> const & rhs) | |
319 { | |
320 T at = a + rhs.real(); // exception guard | |
321 T bt = b + rhs.imag(); // exception guard | |
322 | |
323 a = at; | |
324 b = bt; | |
325 | |
326 return(*this); | |
327 } | |
328 | |
329 | |
330 octonion<T> & operator += (::boost::math::quaternion<T> const & rhs) | |
331 { | |
332 T at = a + rhs.R_component_1(); // exception guard | |
333 T bt = b + rhs.R_component_2(); // exception guard | |
334 T ct = c + rhs.R_component_3(); // exception guard | |
335 T dt = d + rhs.R_component_4(); // exception guard | |
336 | |
337 a = at; | |
338 b = bt; | |
339 c = ct; | |
340 d = dt; | |
341 | |
342 return(*this); | |
343 } | |
344 | |
345 | |
346 template<typename X> | |
347 octonion<T> & operator += (octonion<X> const & rhs) | |
348 { | |
349 T at = a + static_cast<T>(rhs.R_component_1()); // exception guard | |
350 T bt = b + static_cast<T>(rhs.R_component_2()); // exception guard | |
351 T ct = c + static_cast<T>(rhs.R_component_3()); // exception guard | |
352 T dt = d + static_cast<T>(rhs.R_component_4()); // exception guard | |
353 T et = e + static_cast<T>(rhs.R_component_5()); // exception guard | |
354 T ft = f + static_cast<T>(rhs.R_component_6()); // exception guard | |
355 T gt = g + static_cast<T>(rhs.R_component_7()); // exception guard | |
356 T ht = h + static_cast<T>(rhs.R_component_8()); // exception guard | |
357 | |
358 a = at; | |
359 b = bt; | |
360 c = ct; | |
361 d = dt; | |
362 e = et; | |
363 f = ft; | |
364 g = gt; | |
365 h = ht; | |
366 | |
367 return(*this); | |
368 } | |
369 | |
370 | |
371 | |
372 octonion<T> & operator -= (T const & rhs) | |
373 { | |
374 T at = a - rhs; // exception guard | |
375 | |
376 a = at; | |
377 | |
378 return(*this); | |
379 } | |
380 | |
381 | |
382 octonion<T> & operator -= (::std::complex<T> const & rhs) | |
383 { | |
384 T at = a - rhs.real(); // exception guard | |
385 T bt = b - rhs.imag(); // exception guard | |
386 | |
387 a = at; | |
388 b = bt; | |
389 | |
390 return(*this); | |
391 } | |
392 | |
393 | |
394 octonion<T> & operator -= (::boost::math::quaternion<T> const & rhs) | |
395 { | |
396 T at = a - rhs.R_component_1(); // exception guard | |
397 T bt = b - rhs.R_component_2(); // exception guard | |
398 T ct = c - rhs.R_component_3(); // exception guard | |
399 T dt = d - rhs.R_component_4(); // exception guard | |
400 | |
401 a = at; | |
402 b = bt; | |
403 c = ct; | |
404 d = dt; | |
405 | |
406 return(*this); | |
407 } | |
408 | |
409 | |
410 template<typename X> | |
411 octonion<T> & operator -= (octonion<X> const & rhs) | |
412 { | |
413 T at = a - static_cast<T>(rhs.R_component_1()); // exception guard | |
414 T bt = b - static_cast<T>(rhs.R_component_2()); // exception guard | |
415 T ct = c - static_cast<T>(rhs.R_component_3()); // exception guard | |
416 T dt = d - static_cast<T>(rhs.R_component_4()); // exception guard | |
417 T et = e - static_cast<T>(rhs.R_component_5()); // exception guard | |
418 T ft = f - static_cast<T>(rhs.R_component_6()); // exception guard | |
419 T gt = g - static_cast<T>(rhs.R_component_7()); // exception guard | |
420 T ht = h - static_cast<T>(rhs.R_component_8()); // exception guard | |
421 | |
422 a = at; | |
423 b = bt; | |
424 c = ct; | |
425 d = dt; | |
426 e = et; | |
427 f = ft; | |
428 g = gt; | |
429 h = ht; | |
430 | |
431 return(*this); | |
432 } | |
433 | |
434 | |
435 octonion<T> & operator *= (T const & rhs) | |
436 { | |
437 T at = a * rhs; // exception guard | |
438 T bt = b * rhs; // exception guard | |
439 T ct = c * rhs; // exception guard | |
440 T dt = d * rhs; // exception guard | |
441 T et = e * rhs; // exception guard | |
442 T ft = f * rhs; // exception guard | |
443 T gt = g * rhs; // exception guard | |
444 T ht = h * rhs; // exception guard | |
445 | |
446 a = at; | |
447 b = bt; | |
448 c = ct; | |
449 d = dt; | |
450 e = et; | |
451 f = ft; | |
452 g = gt; | |
453 h = ht; | |
454 | |
455 return(*this); | |
456 } | |
457 | |
458 | |
459 octonion<T> & operator *= (::std::complex<T> const & rhs) | |
460 { | |
461 T ar = rhs.real(); | |
462 T br = rhs.imag(); | |
463 | |
464 T at = +a*ar-b*br; | |
465 T bt = +a*br+b*ar; | |
466 T ct = +c*ar+d*br; | |
467 T dt = -c*br+d*ar; | |
468 T et = +e*ar+f*br; | |
469 T ft = -e*br+f*ar; | |
470 T gt = +g*ar-h*br; | |
471 T ht = +g*br+h*ar; | |
472 | |
473 a = at; | |
474 b = bt; | |
475 c = ct; | |
476 d = dt; | |
477 e = et; | |
478 f = ft; | |
479 g = gt; | |
480 h = ht; | |
481 | |
482 return(*this); | |
483 } | |
484 | |
485 | |
486 octonion<T> & operator *= (::boost::math::quaternion<T> const & rhs) | |
487 { | |
488 T ar = rhs.R_component_1(); | |
489 T br = rhs.R_component_2(); | |
490 T cr = rhs.R_component_2(); | |
491 T dr = rhs.R_component_2(); | |
492 | |
493 T at = +a*ar-b*br-c*cr-d*dr; | |
494 T bt = +a*br+b*ar+c*dr-d*cr; | |
495 T ct = +a*cr-b*dr+c*ar+d*br; | |
496 T dt = +a*dr+b*cr-c*br+d*ar; | |
497 T et = +e*ar+f*br+g*cr+h*dr; | |
498 T ft = -e*br+f*ar-g*dr+h*cr; | |
499 T gt = -e*cr+f*dr+g*ar-h*br; | |
500 T ht = -e*dr-f*cr+g*br+h*ar; | |
501 | |
502 a = at; | |
503 b = bt; | |
504 c = ct; | |
505 d = dt; | |
506 e = et; | |
507 f = ft; | |
508 g = gt; | |
509 h = ht; | |
510 | |
511 return(*this); | |
512 } | |
513 | |
514 | |
515 template<typename X> | |
516 octonion<T> & operator *= (octonion<X> const & rhs) | |
517 { | |
518 T ar = static_cast<T>(rhs.R_component_1()); | |
519 T br = static_cast<T>(rhs.R_component_2()); | |
520 T cr = static_cast<T>(rhs.R_component_3()); | |
521 T dr = static_cast<T>(rhs.R_component_4()); | |
522 T er = static_cast<T>(rhs.R_component_5()); | |
523 T fr = static_cast<T>(rhs.R_component_6()); | |
524 T gr = static_cast<T>(rhs.R_component_7()); | |
525 T hr = static_cast<T>(rhs.R_component_8()); | |
526 | |
527 T at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; | |
528 T bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; | |
529 T ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; | |
530 T dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; | |
531 T et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; | |
532 T ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; | |
533 T gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; | |
534 T ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; | |
535 | |
536 a = at; | |
537 b = bt; | |
538 c = ct; | |
539 d = dt; | |
540 e = et; | |
541 f = ft; | |
542 g = gt; | |
543 h = ht; | |
544 | |
545 return(*this); | |
546 } | |
547 | |
548 | |
549 octonion<T> & operator /= (T const & rhs) | |
550 { | |
551 T at = a / rhs; // exception guard | |
552 T bt = b / rhs; // exception guard | |
553 T ct = c / rhs; // exception guard | |
554 T dt = d / rhs; // exception guard | |
555 T et = e / rhs; // exception guard | |
556 T ft = f / rhs; // exception guard | |
557 T gt = g / rhs; // exception guard | |
558 T ht = h / rhs; // exception guard | |
559 | |
560 a = at; | |
561 b = bt; | |
562 c = ct; | |
563 d = dt; | |
564 e = et; | |
565 f = ft; | |
566 g = gt; | |
567 h = ht; | |
568 | |
569 return(*this); | |
570 } | |
571 | |
572 | |
573 octonion<T> & operator /= (::std::complex<T> const & rhs) | |
574 { | |
575 T ar = rhs.real(); | |
576 T br = rhs.imag(); | |
577 | |
578 T denominator = ar*ar+br*br; | |
579 | |
580 T at = (+a*ar-b*br)/denominator; | |
581 T bt = (-a*br+b*ar)/denominator; | |
582 T ct = (+c*ar-d*br)/denominator; | |
583 T dt = (+c*br+d*ar)/denominator; | |
584 T et = (+e*ar-f*br)/denominator; | |
585 T ft = (+e*br+f*ar)/denominator; | |
586 T gt = (+g*ar+h*br)/denominator; | |
587 T ht = (+g*br+h*ar)/denominator; | |
588 | |
589 a = at; | |
590 b = bt; | |
591 c = ct; | |
592 d = dt; | |
593 e = et; | |
594 f = ft; | |
595 g = gt; | |
596 h = ht; | |
597 | |
598 return(*this); | |
599 } | |
600 | |
601 | |
602 octonion<T> & operator /= (::boost::math::quaternion<T> const & rhs) | |
603 { | |
604 T ar = rhs.R_component_1(); | |
605 T br = rhs.R_component_2(); | |
606 T cr = rhs.R_component_2(); | |
607 T dr = rhs.R_component_2(); | |
608 | |
609 T denominator = ar*ar+br*br+cr*cr+dr*dr; | |
610 | |
611 T at = (+a*ar+b*br+c*cr+d*dr)/denominator; | |
612 T bt = (-a*br+b*ar-c*dr+d*cr)/denominator; | |
613 T ct = (-a*cr+b*dr+c*ar-d*br)/denominator; | |
614 T dt = (-a*dr-b*cr+c*br+d*ar)/denominator; | |
615 T et = (+e*ar-f*br-g*cr-h*dr)/denominator; | |
616 T ft = (+e*br+f*ar+g*dr-h*cr)/denominator; | |
617 T gt = (+e*cr-f*dr+g*ar+h*br)/denominator; | |
618 T ht = (+e*dr+f*cr-g*br+h*ar)/denominator; | |
619 | |
620 a = at; | |
621 b = bt; | |
622 c = ct; | |
623 d = dt; | |
624 e = et; | |
625 f = ft; | |
626 g = gt; | |
627 h = ht; | |
628 | |
629 return(*this); | |
630 } | |
631 | |
632 | |
633 template<typename X> | |
634 octonion<T> & operator /= (octonion<X> const & rhs) | |
635 { | |
636 T ar = static_cast<T>(rhs.R_component_1()); | |
637 T br = static_cast<T>(rhs.R_component_2()); | |
638 T cr = static_cast<T>(rhs.R_component_3()); | |
639 T dr = static_cast<T>(rhs.R_component_4()); | |
640 T er = static_cast<T>(rhs.R_component_5()); | |
641 T fr = static_cast<T>(rhs.R_component_6()); | |
642 T gr = static_cast<T>(rhs.R_component_7()); | |
643 T hr = static_cast<T>(rhs.R_component_8()); | |
644 | |
645 T denominator = ar*ar+br*br+cr*cr+dr*dr+er*er+fr*fr+gr*gr+hr*hr; | |
646 | |
647 T at = (+a*ar+b*br+c*cr+d*dr+e*er+f*fr+g*gr+h*hr)/denominator; | |
648 T bt = (-a*br+b*ar-c*dr+d*cr-e*fr+f*er+g*hr-h*gr)/denominator; | |
649 T ct = (-a*cr+b*dr+c*ar-d*br-e*gr-f*hr+g*er+h*fr)/denominator; | |
650 T dt = (-a*dr-b*cr+c*br+d*ar-e*hr+f*gr-g*fr+h*er)/denominator; | |
651 T et = (-a*er+b*fr+c*gr+d*hr+e*ar-f*br-g*cr-h*dr)/denominator; | |
652 T ft = (-a*fr-b*er+c*hr-d*gr+e*br+f*ar+g*dr-h*cr)/denominator; | |
653 T gt = (-a*gr-b*hr-c*er+d*fr+e*cr-f*dr+g*ar+h*br)/denominator; | |
654 T ht = (-a*hr+b*gr-c*fr-d*er+e*dr+f*cr-g*br+h*ar)/denominator; | |
655 | |
656 a = at; | |
657 b = bt; | |
658 c = ct; | |
659 d = dt; | |
660 e = et; | |
661 f = ft; | |
662 g = gt; | |
663 h = ht; | |
664 | |
665 return(*this); | |
666 } | |
667 | |
668 | |
669 protected: | |
670 | |
671 BOOST_OCTONION_MEMBER_DATA_GENERATOR(T) | |
672 | |
673 | |
674 private: | |
675 | |
676 }; | |
677 | |
678 | |
679 // declaration of octonion specialization | |
680 | |
681 template<> class octonion<float>; | |
682 template<> class octonion<double>; | |
683 template<> class octonion<long double>; | |
684 | |
685 | |
686 // helper templates for converting copy constructors (declaration) | |
687 | |
688 namespace detail | |
689 { | |
690 | |
691 template< typename T, | |
692 typename U | |
693 > | |
694 octonion<T> octonion_type_converter(octonion<U> const & rhs); | |
695 } | |
696 | |
697 | |
698 // implementation of octonion specialization | |
699 | |
700 | |
701 #define BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type) \ | |
702 explicit octonion( type const & requested_a = static_cast<type>(0), \ | |
703 type const & requested_b = static_cast<type>(0), \ | |
704 type const & requested_c = static_cast<type>(0), \ | |
705 type const & requested_d = static_cast<type>(0), \ | |
706 type const & requested_e = static_cast<type>(0), \ | |
707 type const & requested_f = static_cast<type>(0), \ | |
708 type const & requested_g = static_cast<type>(0), \ | |
709 type const & requested_h = static_cast<type>(0)) \ | |
710 : a(requested_a), \ | |
711 b(requested_b), \ | |
712 c(requested_c), \ | |
713 d(requested_d), \ | |
714 e(requested_e), \ | |
715 f(requested_f), \ | |
716 g(requested_g), \ | |
717 h(requested_h) \ | |
718 { \ | |
719 } \ | |
720 \ | |
721 explicit octonion( ::std::complex<type> const & z0, \ | |
722 ::std::complex<type> const & z1 = ::std::complex<type>(), \ | |
723 ::std::complex<type> const & z2 = ::std::complex<type>(), \ | |
724 ::std::complex<type> const & z3 = ::std::complex<type>()) \ | |
725 : a(z0.real()), \ | |
726 b(z0.imag()), \ | |
727 c(z1.real()), \ | |
728 d(z1.imag()), \ | |
729 e(z2.real()), \ | |
730 f(z2.imag()), \ | |
731 g(z3.real()), \ | |
732 h(z3.imag()) \ | |
733 { \ | |
734 } \ | |
735 \ | |
736 explicit octonion( ::boost::math::quaternion<type> const & q0, \ | |
737 ::boost::math::quaternion<type> const & q1 = ::boost::math::quaternion<type>()) \ | |
738 : a(q0.R_component_1()), \ | |
739 b(q0.R_component_2()), \ | |
740 c(q0.R_component_3()), \ | |
741 d(q0.R_component_4()), \ | |
742 e(q1.R_component_1()), \ | |
743 f(q1.R_component_2()), \ | |
744 g(q1.R_component_3()), \ | |
745 h(q1.R_component_4()) \ | |
746 { \ | |
747 } | |
748 | |
749 | |
750 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \ | |
751 octonion<type> & operator += (type const & rhs) \ | |
752 { \ | |
753 a += rhs; \ | |
754 \ | |
755 return(*this); \ | |
756 } | |
757 | |
758 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \ | |
759 octonion<type> & operator += (::std::complex<type> const & rhs) \ | |
760 { \ | |
761 a += rhs.real(); \ | |
762 b += rhs.imag(); \ | |
763 \ | |
764 return(*this); \ | |
765 } | |
766 | |
767 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \ | |
768 octonion<type> & operator += (::boost::math::quaternion<type> const & rhs) \ | |
769 { \ | |
770 a += rhs.R_component_1(); \ | |
771 b += rhs.R_component_2(); \ | |
772 c += rhs.R_component_3(); \ | |
773 d += rhs.R_component_4(); \ | |
774 \ | |
775 return(*this); \ | |
776 } | |
777 | |
778 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) \ | |
779 template<typename X> \ | |
780 octonion<type> & operator += (octonion<X> const & rhs) \ | |
781 { \ | |
782 a += static_cast<type>(rhs.R_component_1()); \ | |
783 b += static_cast<type>(rhs.R_component_2()); \ | |
784 c += static_cast<type>(rhs.R_component_3()); \ | |
785 d += static_cast<type>(rhs.R_component_4()); \ | |
786 e += static_cast<type>(rhs.R_component_5()); \ | |
787 f += static_cast<type>(rhs.R_component_6()); \ | |
788 g += static_cast<type>(rhs.R_component_7()); \ | |
789 h += static_cast<type>(rhs.R_component_8()); \ | |
790 \ | |
791 return(*this); \ | |
792 } | |
793 | |
794 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \ | |
795 octonion<type> & operator -= (type const & rhs) \ | |
796 { \ | |
797 a -= rhs; \ | |
798 \ | |
799 return(*this); \ | |
800 } | |
801 | |
802 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \ | |
803 octonion<type> & operator -= (::std::complex<type> const & rhs) \ | |
804 { \ | |
805 a -= rhs.real(); \ | |
806 b -= rhs.imag(); \ | |
807 \ | |
808 return(*this); \ | |
809 } | |
810 | |
811 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \ | |
812 octonion<type> & operator -= (::boost::math::quaternion<type> const & rhs) \ | |
813 { \ | |
814 a -= rhs.R_component_1(); \ | |
815 b -= rhs.R_component_2(); \ | |
816 c -= rhs.R_component_3(); \ | |
817 d -= rhs.R_component_4(); \ | |
818 \ | |
819 return(*this); \ | |
820 } | |
821 | |
822 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) \ | |
823 template<typename X> \ | |
824 octonion<type> & operator -= (octonion<X> const & rhs) \ | |
825 { \ | |
826 a -= static_cast<type>(rhs.R_component_1()); \ | |
827 b -= static_cast<type>(rhs.R_component_2()); \ | |
828 c -= static_cast<type>(rhs.R_component_3()); \ | |
829 d -= static_cast<type>(rhs.R_component_4()); \ | |
830 e -= static_cast<type>(rhs.R_component_5()); \ | |
831 f -= static_cast<type>(rhs.R_component_6()); \ | |
832 g -= static_cast<type>(rhs.R_component_7()); \ | |
833 h -= static_cast<type>(rhs.R_component_8()); \ | |
834 \ | |
835 return(*this); \ | |
836 } | |
837 | |
838 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \ | |
839 octonion<type> & operator *= (type const & rhs) \ | |
840 { \ | |
841 a *= rhs; \ | |
842 b *= rhs; \ | |
843 c *= rhs; \ | |
844 d *= rhs; \ | |
845 e *= rhs; \ | |
846 f *= rhs; \ | |
847 g *= rhs; \ | |
848 h *= rhs; \ | |
849 \ | |
850 return(*this); \ | |
851 } | |
852 | |
853 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \ | |
854 octonion<type> & operator *= (::std::complex<type> const & rhs) \ | |
855 { \ | |
856 type ar = rhs.real(); \ | |
857 type br = rhs.imag(); \ | |
858 \ | |
859 type at = +a*ar-b*br; \ | |
860 type bt = +a*br+b*ar; \ | |
861 type ct = +c*ar+d*br; \ | |
862 type dt = -c*br+d*ar; \ | |
863 type et = +e*ar+f*br; \ | |
864 type ft = -e*br+f*ar; \ | |
865 type gt = +g*ar-h*br; \ | |
866 type ht = +g*br+h*ar; \ | |
867 \ | |
868 a = at; \ | |
869 b = bt; \ | |
870 c = ct; \ | |
871 d = dt; \ | |
872 e = et; \ | |
873 f = ft; \ | |
874 g = gt; \ | |
875 h = ht; \ | |
876 \ | |
877 return(*this); \ | |
878 } | |
879 | |
880 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \ | |
881 octonion<type> & operator *= (::boost::math::quaternion<type> const & rhs) \ | |
882 { \ | |
883 type ar = rhs.R_component_1(); \ | |
884 type br = rhs.R_component_2(); \ | |
885 type cr = rhs.R_component_2(); \ | |
886 type dr = rhs.R_component_2(); \ | |
887 \ | |
888 type at = +a*ar-b*br-c*cr-d*dr; \ | |
889 type bt = +a*br+b*ar+c*dr-d*cr; \ | |
890 type ct = +a*cr-b*dr+c*ar+d*br; \ | |
891 type dt = +a*dr+b*cr-c*br+d*ar; \ | |
892 type et = +e*ar+f*br+g*cr+h*dr; \ | |
893 type ft = -e*br+f*ar-g*dr+h*cr; \ | |
894 type gt = -e*cr+f*dr+g*ar-h*br; \ | |
895 type ht = -e*dr-f*cr+g*br+h*ar; \ | |
896 \ | |
897 a = at; \ | |
898 b = bt; \ | |
899 c = ct; \ | |
900 d = dt; \ | |
901 e = et; \ | |
902 f = ft; \ | |
903 g = gt; \ | |
904 h = ht; \ | |
905 \ | |
906 return(*this); \ | |
907 } | |
908 | |
909 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) \ | |
910 template<typename X> \ | |
911 octonion<type> & operator *= (octonion<X> const & rhs) \ | |
912 { \ | |
913 type ar = static_cast<type>(rhs.R_component_1()); \ | |
914 type br = static_cast<type>(rhs.R_component_2()); \ | |
915 type cr = static_cast<type>(rhs.R_component_3()); \ | |
916 type dr = static_cast<type>(rhs.R_component_4()); \ | |
917 type er = static_cast<type>(rhs.R_component_5()); \ | |
918 type fr = static_cast<type>(rhs.R_component_6()); \ | |
919 type gr = static_cast<type>(rhs.R_component_7()); \ | |
920 type hr = static_cast<type>(rhs.R_component_8()); \ | |
921 \ | |
922 type at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; \ | |
923 type bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; \ | |
924 type ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; \ | |
925 type dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; \ | |
926 type et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; \ | |
927 type ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; \ | |
928 type gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; \ | |
929 type ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; \ | |
930 \ | |
931 a = at; \ | |
932 b = bt; \ | |
933 c = ct; \ | |
934 d = dt; \ | |
935 e = et; \ | |
936 f = ft; \ | |
937 g = gt; \ | |
938 h = ht; \ | |
939 \ | |
940 return(*this); \ | |
941 } | |
942 | |
943 // There is quite a lot of repetition in the code below. This is intentional. | |
944 // The last conditional block is the normal form, and the others merely | |
945 // consist of workarounds for various compiler deficiencies. Hopefuly, when | |
946 // more compilers are conformant and we can retire support for those that are | |
947 // not, we will be able to remove the clutter. This is makes the situation | |
948 // (painfully) explicit. | |
949 | |
950 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \ | |
951 octonion<type> & operator /= (type const & rhs) \ | |
952 { \ | |
953 a /= rhs; \ | |
954 b /= rhs; \ | |
955 c /= rhs; \ | |
956 d /= rhs; \ | |
957 \ | |
958 return(*this); \ | |
959 } | |
960 | |
961 #if defined(__GNUC__) && (__GNUC__ < 3) | |
962 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ | |
963 octonion<type> & operator /= (::std::complex<type> const & rhs) \ | |
964 { \ | |
965 using ::std::valarray; \ | |
966 \ | |
967 valarray<type> tr(2); \ | |
968 \ | |
969 tr[0] = rhs.real(); \ | |
970 tr[1] = rhs.imag(); \ | |
971 \ | |
972 type mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)(); \ | |
973 \ | |
974 tr *= mixam; \ | |
975 \ | |
976 valarray<type> tt(8); \ | |
977 \ | |
978 tt[0] = +a*tr[0]-b*tr[1]; \ | |
979 tt[1] = -a*tr[1]+b*tr[0]; \ | |
980 tt[2] = +c*tr[0]-d*tr[1]; \ | |
981 tt[3] = +c*tr[1]+d*tr[0]; \ | |
982 tt[4] = +e*tr[0]-f*tr[1]; \ | |
983 tt[5] = +e*tr[1]+f*tr[0]; \ | |
984 tt[6] = +g*tr[0]+h*tr[1]; \ | |
985 tt[7] = +g*tr[1]+h*tr[0]; \ | |
986 \ | |
987 tr *= tr; \ | |
988 \ | |
989 tt *= (mixam/tr.sum()); \ | |
990 \ | |
991 a = tt[0]; \ | |
992 b = tt[1]; \ | |
993 c = tt[2]; \ | |
994 d = tt[3]; \ | |
995 e = tt[4]; \ | |
996 f = tt[5]; \ | |
997 g = tt[6]; \ | |
998 h = tt[7]; \ | |
999 \ | |
1000 return(*this); \ | |
1001 } | |
1002 #elif defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
1003 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ | |
1004 octonion<type> & operator /= (::std::complex<type> const & rhs) \ | |
1005 { \ | |
1006 using ::std::valarray; \ | |
1007 using ::std::abs; \ | |
1008 \ | |
1009 valarray<type> tr(2); \ | |
1010 \ | |
1011 tr[0] = rhs.real(); \ | |
1012 tr[1] = rhs.imag(); \ | |
1013 \ | |
1014 type mixam = static_cast<type>(1)/(abs(tr).max)(); \ | |
1015 \ | |
1016 tr *= mixam; \ | |
1017 \ | |
1018 valarray<type> tt(8); \ | |
1019 \ | |
1020 tt[0] = +a*tr[0]-b*tr[1]; \ | |
1021 tt[1] = -a*tr[1]+b*tr[0]; \ | |
1022 tt[2] = +c*tr[0]-d*tr[1]; \ | |
1023 tt[3] = +c*tr[1]+d*tr[0]; \ | |
1024 tt[4] = +e*tr[0]-f*tr[1]; \ | |
1025 tt[5] = +e*tr[1]+f*tr[0]; \ | |
1026 tt[6] = +g*tr[0]+h*tr[1]; \ | |
1027 tt[7] = +g*tr[1]+h*tr[0]; \ | |
1028 \ | |
1029 tr *= tr; \ | |
1030 \ | |
1031 tt *= (mixam/tr.sum()); \ | |
1032 \ | |
1033 a = tt[0]; \ | |
1034 b = tt[1]; \ | |
1035 c = tt[2]; \ | |
1036 d = tt[3]; \ | |
1037 e = tt[4]; \ | |
1038 f = tt[5]; \ | |
1039 g = tt[6]; \ | |
1040 h = tt[7]; \ | |
1041 \ | |
1042 return(*this); \ | |
1043 } | |
1044 #else | |
1045 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ | |
1046 octonion<type> & operator /= (::std::complex<type> const & rhs) \ | |
1047 { \ | |
1048 using ::std::valarray; \ | |
1049 \ | |
1050 valarray<type> tr(2); \ | |
1051 \ | |
1052 tr[0] = rhs.real(); \ | |
1053 tr[1] = rhs.imag(); \ | |
1054 \ | |
1055 type mixam = static_cast<type>(1)/(abs(tr).max)(); \ | |
1056 \ | |
1057 tr *= mixam; \ | |
1058 \ | |
1059 valarray<type> tt(8); \ | |
1060 \ | |
1061 tt[0] = +a*tr[0]-b*tr[1]; \ | |
1062 tt[1] = -a*tr[1]+b*tr[0]; \ | |
1063 tt[2] = +c*tr[0]-d*tr[1]; \ | |
1064 tt[3] = +c*tr[1]+d*tr[0]; \ | |
1065 tt[4] = +e*tr[0]-f*tr[1]; \ | |
1066 tt[5] = +e*tr[1]+f*tr[0]; \ | |
1067 tt[6] = +g*tr[0]+h*tr[1]; \ | |
1068 tt[7] = +g*tr[1]+h*tr[0]; \ | |
1069 \ | |
1070 tr *= tr; \ | |
1071 \ | |
1072 tt *= (mixam/tr.sum()); \ | |
1073 \ | |
1074 a = tt[0]; \ | |
1075 b = tt[1]; \ | |
1076 c = tt[2]; \ | |
1077 d = tt[3]; \ | |
1078 e = tt[4]; \ | |
1079 f = tt[5]; \ | |
1080 g = tt[6]; \ | |
1081 h = tt[7]; \ | |
1082 \ | |
1083 return(*this); \ | |
1084 } | |
1085 #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | |
1086 | |
1087 #if defined(__GNUC__) && (__GNUC__ < 3) | |
1088 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ | |
1089 octonion<type> & operator /= (::boost::math::quaternion<type> const & rhs) \ | |
1090 { \ | |
1091 using ::std::valarray; \ | |
1092 \ | |
1093 valarray<type> tr(4); \ | |
1094 \ | |
1095 tr[0] = static_cast<type>(rhs.R_component_1()); \ | |
1096 tr[1] = static_cast<type>(rhs.R_component_2()); \ | |
1097 tr[2] = static_cast<type>(rhs.R_component_3()); \ | |
1098 tr[3] = static_cast<type>(rhs.R_component_4()); \ | |
1099 \ | |
1100 type mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();\ | |
1101 \ | |
1102 tr *= mixam; \ | |
1103 \ | |
1104 valarray<type> tt(8); \ | |
1105 \ | |
1106 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ | |
1107 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ | |
1108 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ | |
1109 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ | |
1110 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ | |
1111 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ | |
1112 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ | |
1113 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ | |
1114 \ | |
1115 tr *= tr; \ | |
1116 \ | |
1117 tt *= (mixam/tr.sum()); \ | |
1118 \ | |
1119 a = tt[0]; \ | |
1120 b = tt[1]; \ | |
1121 c = tt[2]; \ | |
1122 d = tt[3]; \ | |
1123 e = tt[4]; \ | |
1124 f = tt[5]; \ | |
1125 g = tt[6]; \ | |
1126 h = tt[7]; \ | |
1127 \ | |
1128 return(*this); \ | |
1129 } | |
1130 #elif defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
1131 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ | |
1132 octonion<type> & operator /= (::boost::math::quaternion<type> const & rhs) \ | |
1133 { \ | |
1134 using ::std::valarray; \ | |
1135 using ::std::abs; \ | |
1136 \ | |
1137 valarray<type> tr(4); \ | |
1138 \ | |
1139 tr[0] = static_cast<type>(rhs.R_component_1()); \ | |
1140 tr[1] = static_cast<type>(rhs.R_component_2()); \ | |
1141 tr[2] = static_cast<type>(rhs.R_component_3()); \ | |
1142 tr[3] = static_cast<type>(rhs.R_component_4()); \ | |
1143 \ | |
1144 type mixam = static_cast<type>(1)/(abs(tr).max)(); \ | |
1145 \ | |
1146 tr *= mixam; \ | |
1147 \ | |
1148 valarray<type> tt(8); \ | |
1149 \ | |
1150 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ | |
1151 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ | |
1152 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ | |
1153 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ | |
1154 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ | |
1155 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ | |
1156 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ | |
1157 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ | |
1158 \ | |
1159 tr *= tr; \ | |
1160 \ | |
1161 tt *= (mixam/tr.sum()); \ | |
1162 \ | |
1163 a = tt[0]; \ | |
1164 b = tt[1]; \ | |
1165 c = tt[2]; \ | |
1166 d = tt[3]; \ | |
1167 e = tt[4]; \ | |
1168 f = tt[5]; \ | |
1169 g = tt[6]; \ | |
1170 h = tt[7]; \ | |
1171 \ | |
1172 return(*this); \ | |
1173 } | |
1174 #else | |
1175 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ | |
1176 octonion<type> & operator /= (::boost::math::quaternion<type> const & rhs) \ | |
1177 { \ | |
1178 using ::std::valarray; \ | |
1179 \ | |
1180 valarray<type> tr(4); \ | |
1181 \ | |
1182 tr[0] = static_cast<type>(rhs.R_component_1()); \ | |
1183 tr[1] = static_cast<type>(rhs.R_component_2()); \ | |
1184 tr[2] = static_cast<type>(rhs.R_component_3()); \ | |
1185 tr[3] = static_cast<type>(rhs.R_component_4()); \ | |
1186 \ | |
1187 type mixam = static_cast<type>(1)/(abs(tr).max)(); \ | |
1188 \ | |
1189 tr *= mixam; \ | |
1190 \ | |
1191 valarray<type> tt(8); \ | |
1192 \ | |
1193 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ | |
1194 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ | |
1195 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ | |
1196 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ | |
1197 tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ | |
1198 tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ | |
1199 tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ | |
1200 tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ | |
1201 \ | |
1202 tr *= tr; \ | |
1203 \ | |
1204 tt *= (mixam/tr.sum()); \ | |
1205 \ | |
1206 a = tt[0]; \ | |
1207 b = tt[1]; \ | |
1208 c = tt[2]; \ | |
1209 d = tt[3]; \ | |
1210 e = tt[4]; \ | |
1211 f = tt[5]; \ | |
1212 g = tt[6]; \ | |
1213 h = tt[7]; \ | |
1214 \ | |
1215 return(*this); \ | |
1216 } | |
1217 #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | |
1218 | |
1219 #if defined(__GNUC__) && (__GNUC__ < 3) | |
1220 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ | |
1221 template<typename X> \ | |
1222 octonion<type> & operator /= (octonion<X> const & rhs) \ | |
1223 { \ | |
1224 using ::std::valarray; \ | |
1225 \ | |
1226 valarray<type> tr(8); \ | |
1227 \ | |
1228 tr[0] = static_cast<type>(rhs.R_component_1()); \ | |
1229 tr[1] = static_cast<type>(rhs.R_component_2()); \ | |
1230 tr[2] = static_cast<type>(rhs.R_component_3()); \ | |
1231 tr[3] = static_cast<type>(rhs.R_component_4()); \ | |
1232 tr[4] = static_cast<type>(rhs.R_component_5()); \ | |
1233 tr[5] = static_cast<type>(rhs.R_component_6()); \ | |
1234 tr[6] = static_cast<type>(rhs.R_component_7()); \ | |
1235 tr[7] = static_cast<type>(rhs.R_component_8()); \ | |
1236 \ | |
1237 type mixam = (BOOST_GET_VALARRAY(type,static_cast<type>(1)/abs(tr)).max)();\ | |
1238 \ | |
1239 tr *= mixam; \ | |
1240 \ | |
1241 valarray<type> tt(8); \ | |
1242 \ | |
1243 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ | |
1244 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ | |
1245 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ | |
1246 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ | |
1247 tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ | |
1248 tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ | |
1249 tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ | |
1250 tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ | |
1251 \ | |
1252 tr *= tr; \ | |
1253 \ | |
1254 tt *= (mixam/tr.sum()); \ | |
1255 \ | |
1256 a = tt[0]; \ | |
1257 b = tt[1]; \ | |
1258 c = tt[2]; \ | |
1259 d = tt[3]; \ | |
1260 e = tt[4]; \ | |
1261 f = tt[5]; \ | |
1262 g = tt[6]; \ | |
1263 h = tt[7]; \ | |
1264 \ | |
1265 return(*this); \ | |
1266 } | |
1267 #elif defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) | |
1268 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ | |
1269 template<typename X> \ | |
1270 octonion<type> & operator /= (octonion<X> const & rhs) \ | |
1271 { \ | |
1272 using ::std::valarray; \ | |
1273 using ::std::abs; \ | |
1274 \ | |
1275 valarray<type> tr(8); \ | |
1276 \ | |
1277 tr[0] = static_cast<type>(rhs.R_component_1()); \ | |
1278 tr[1] = static_cast<type>(rhs.R_component_2()); \ | |
1279 tr[2] = static_cast<type>(rhs.R_component_3()); \ | |
1280 tr[3] = static_cast<type>(rhs.R_component_4()); \ | |
1281 tr[4] = static_cast<type>(rhs.R_component_5()); \ | |
1282 tr[5] = static_cast<type>(rhs.R_component_6()); \ | |
1283 tr[6] = static_cast<type>(rhs.R_component_7()); \ | |
1284 tr[7] = static_cast<type>(rhs.R_component_8()); \ | |
1285 \ | |
1286 type mixam = static_cast<type>(1)/(abs(tr).max)(); \ | |
1287 \ | |
1288 tr *= mixam; \ | |
1289 \ | |
1290 valarray<type> tt(8); \ | |
1291 \ | |
1292 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ | |
1293 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ | |
1294 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ | |
1295 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ | |
1296 tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ | |
1297 tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ | |
1298 tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ | |
1299 tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ | |
1300 \ | |
1301 tr *= tr; \ | |
1302 \ | |
1303 tt *= (mixam/tr.sum()); \ | |
1304 \ | |
1305 a = tt[0]; \ | |
1306 b = tt[1]; \ | |
1307 c = tt[2]; \ | |
1308 d = tt[3]; \ | |
1309 e = tt[4]; \ | |
1310 f = tt[5]; \ | |
1311 g = tt[6]; \ | |
1312 h = tt[7]; \ | |
1313 \ | |
1314 return(*this); \ | |
1315 } | |
1316 #else | |
1317 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ | |
1318 template<typename X> \ | |
1319 octonion<type> & operator /= (octonion<X> const & rhs) \ | |
1320 { \ | |
1321 using ::std::valarray; \ | |
1322 \ | |
1323 valarray<type> tr(8); \ | |
1324 \ | |
1325 tr[0] = static_cast<type>(rhs.R_component_1()); \ | |
1326 tr[1] = static_cast<type>(rhs.R_component_2()); \ | |
1327 tr[2] = static_cast<type>(rhs.R_component_3()); \ | |
1328 tr[3] = static_cast<type>(rhs.R_component_4()); \ | |
1329 tr[4] = static_cast<type>(rhs.R_component_5()); \ | |
1330 tr[5] = static_cast<type>(rhs.R_component_6()); \ | |
1331 tr[6] = static_cast<type>(rhs.R_component_7()); \ | |
1332 tr[7] = static_cast<type>(rhs.R_component_8()); \ | |
1333 \ | |
1334 type mixam = static_cast<type>(1)/(abs(tr).max)(); \ | |
1335 \ | |
1336 tr *= mixam; \ | |
1337 \ | |
1338 valarray<type> tt(8); \ | |
1339 \ | |
1340 tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ | |
1341 tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ | |
1342 tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ | |
1343 tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ | |
1344 tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ | |
1345 tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ | |
1346 tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ | |
1347 tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ | |
1348 \ | |
1349 tr *= tr; \ | |
1350 \ | |
1351 tt *= (mixam/tr.sum()); \ | |
1352 \ | |
1353 a = tt[0]; \ | |
1354 b = tt[1]; \ | |
1355 c = tt[2]; \ | |
1356 d = tt[3]; \ | |
1357 e = tt[4]; \ | |
1358 f = tt[5]; \ | |
1359 g = tt[6]; \ | |
1360 h = tt[7]; \ | |
1361 \ | |
1362 return(*this); \ | |
1363 } | |
1364 #endif /* defined(__GNUC__) && (__GNUC__ < 3) */ /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | |
1365 | |
1366 | |
1367 #define BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \ | |
1368 BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \ | |
1369 BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \ | |
1370 BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \ | |
1371 BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) | |
1372 | |
1373 #define BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \ | |
1374 BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \ | |
1375 BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \ | |
1376 BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \ | |
1377 BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) | |
1378 | |
1379 #define BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \ | |
1380 BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \ | |
1381 BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \ | |
1382 BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \ | |
1383 BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) | |
1384 | |
1385 #define BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) \ | |
1386 BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \ | |
1387 BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ | |
1388 BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ | |
1389 BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) | |
1390 | |
1391 #define BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \ | |
1392 BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \ | |
1393 BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \ | |
1394 BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \ | |
1395 BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) | |
1396 | |
1397 | |
1398 template<> | |
1399 class octonion<float> | |
1400 { | |
1401 public: | |
1402 | |
1403 typedef float value_type; | |
1404 | |
1405 BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float) | |
1406 | |
1407 // UNtemplated copy constructor | |
1408 // (this is taken care of by the compiler itself) | |
1409 | |
1410 // explicit copy constructors (precision-loosing converters) | |
1411 | |
1412 explicit octonion(octonion<double> const & a_recopier) | |
1413 { | |
1414 *this = detail::octonion_type_converter<float, double>(a_recopier); | |
1415 } | |
1416 | |
1417 explicit octonion(octonion<long double> const & a_recopier) | |
1418 { | |
1419 *this = detail::octonion_type_converter<float, long double>(a_recopier); | |
1420 } | |
1421 | |
1422 // destructor | |
1423 // (this is taken care of by the compiler itself) | |
1424 | |
1425 // accessors | |
1426 // | |
1427 // Note: Like complex number, octonions do have a meaningful notion of "real part", | |
1428 // but unlike them there is no meaningful notion of "imaginary part". | |
1429 // Instead there is an "unreal part" which itself is an octonion, and usually | |
1430 // nothing simpler (as opposed to the complex number case). | |
1431 // However, for practicallity, there are accessors for the other components | |
1432 // (these are necessary for the templated copy constructor, for instance). | |
1433 | |
1434 BOOST_OCTONION_ACCESSOR_GENERATOR(float) | |
1435 | |
1436 // assignment operators | |
1437 | |
1438 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float) | |
1439 | |
1440 // other assignment-related operators | |
1441 // | |
1442 // NOTE: Octonion multiplication is *NOT* commutative; | |
1443 // symbolically, "q *= rhs;" means "q = q * rhs;" | |
1444 // and "q /= rhs;" means "q = q * inverse_of(rhs);"; | |
1445 // octonion multiplication is also *NOT* associative | |
1446 | |
1447 BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float) | |
1448 | |
1449 | |
1450 protected: | |
1451 | |
1452 BOOST_OCTONION_MEMBER_DATA_GENERATOR(float) | |
1453 | |
1454 | |
1455 private: | |
1456 | |
1457 }; | |
1458 | |
1459 | |
1460 template<> | |
1461 class octonion<double> | |
1462 { | |
1463 public: | |
1464 | |
1465 typedef double value_type; | |
1466 | |
1467 BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double) | |
1468 | |
1469 // UNtemplated copy constructor | |
1470 // (this is taken care of by the compiler itself) | |
1471 | |
1472 // converting copy constructor | |
1473 | |
1474 explicit octonion(octonion<float> const & a_recopier) | |
1475 { | |
1476 *this = detail::octonion_type_converter<double, float>(a_recopier); | |
1477 } | |
1478 | |
1479 // explicit copy constructors (precision-loosing converters) | |
1480 | |
1481 explicit octonion(octonion<long double> const & a_recopier) | |
1482 { | |
1483 *this = detail::octonion_type_converter<double, long double>(a_recopier); | |
1484 } | |
1485 | |
1486 // destructor | |
1487 // (this is taken care of by the compiler itself) | |
1488 | |
1489 // accessors | |
1490 // | |
1491 // Note: Like complex number, octonions do have a meaningful notion of "real part", | |
1492 // but unlike them there is no meaningful notion of "imaginary part". | |
1493 // Instead there is an "unreal part" which itself is an octonion, and usually | |
1494 // nothing simpler (as opposed to the complex number case). | |
1495 // However, for practicallity, there are accessors for the other components | |
1496 // (these are necessary for the templated copy constructor, for instance). | |
1497 | |
1498 BOOST_OCTONION_ACCESSOR_GENERATOR(double) | |
1499 | |
1500 // assignment operators | |
1501 | |
1502 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double) | |
1503 | |
1504 // other assignment-related operators | |
1505 // | |
1506 // NOTE: Octonion multiplication is *NOT* commutative; | |
1507 // symbolically, "q *= rhs;" means "q = q * rhs;" | |
1508 // and "q /= rhs;" means "q = q * inverse_of(rhs);"; | |
1509 // octonion multiplication is also *NOT* associative | |
1510 | |
1511 BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double) | |
1512 | |
1513 | |
1514 protected: | |
1515 | |
1516 BOOST_OCTONION_MEMBER_DATA_GENERATOR(double) | |
1517 | |
1518 | |
1519 private: | |
1520 | |
1521 }; | |
1522 | |
1523 | |
1524 template<> | |
1525 class octonion<long double> | |
1526 { | |
1527 public: | |
1528 | |
1529 typedef long double value_type; | |
1530 | |
1531 BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double) | |
1532 | |
1533 // UNtemplated copy constructor | |
1534 // (this is taken care of by the compiler itself) | |
1535 | |
1536 // converting copy constructor | |
1537 | |
1538 explicit octonion(octonion<float> const & a_recopier) | |
1539 { | |
1540 *this = detail::octonion_type_converter<long double, float>(a_recopier); | |
1541 } | |
1542 | |
1543 | |
1544 explicit octonion(octonion<double> const & a_recopier) | |
1545 { | |
1546 *this = detail::octonion_type_converter<long double, double>(a_recopier); | |
1547 } | |
1548 | |
1549 | |
1550 // destructor | |
1551 // (this is taken care of by the compiler itself) | |
1552 | |
1553 // accessors | |
1554 // | |
1555 // Note: Like complex number, octonions do have a meaningful notion of "real part", | |
1556 // but unlike them there is no meaningful notion of "imaginary part". | |
1557 // Instead there is an "unreal part" which itself is an octonion, and usually | |
1558 // nothing simpler (as opposed to the complex number case). | |
1559 // However, for practicallity, there are accessors for the other components | |
1560 // (these are necessary for the templated copy constructor, for instance). | |
1561 | |
1562 BOOST_OCTONION_ACCESSOR_GENERATOR(long double) | |
1563 | |
1564 // assignment operators | |
1565 | |
1566 BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double) | |
1567 | |
1568 // other assignment-related operators | |
1569 // | |
1570 // NOTE: Octonion multiplication is *NOT* commutative; | |
1571 // symbolically, "q *= rhs;" means "q = q * rhs;" | |
1572 // and "q /= rhs;" means "q = q * inverse_of(rhs);"; | |
1573 // octonion multiplication is also *NOT* associative | |
1574 | |
1575 BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double) | |
1576 | |
1577 | |
1578 protected: | |
1579 | |
1580 BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double) | |
1581 | |
1582 | |
1583 private: | |
1584 | |
1585 }; | |
1586 | |
1587 | |
1588 #undef BOOST_OCTONION_CONSTRUCTOR_GENERATOR | |
1589 | |
1590 #undef BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR | |
1591 | |
1592 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR | |
1593 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR | |
1594 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR | |
1595 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR | |
1596 | |
1597 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_1 | |
1598 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_2 | |
1599 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_3 | |
1600 #undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_4 | |
1601 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_1 | |
1602 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_2 | |
1603 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_3 | |
1604 #undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_4 | |
1605 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_1 | |
1606 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_2 | |
1607 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_3 | |
1608 #undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_4 | |
1609 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_1 | |
1610 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_2 | |
1611 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_3 | |
1612 #undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_4 | |
1613 | |
1614 | |
1615 #undef BOOST_OCTONION_MEMBER_DATA_GENERATOR | |
1616 | |
1617 #undef BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR | |
1618 | |
1619 #undef BOOST_OCTONION_ACCESSOR_GENERATOR | |
1620 | |
1621 | |
1622 // operators | |
1623 | |
1624 #define BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \ | |
1625 { \ | |
1626 octonion<T> res(lhs); \ | |
1627 res op##= rhs; \ | |
1628 return(res); \ | |
1629 } | |
1630 | |
1631 #define BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \ | |
1632 template<typename T> \ | |
1633 inline octonion<T> operator op (T const & lhs, octonion<T> const & rhs) \ | |
1634 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1635 | |
1636 #define BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \ | |
1637 template<typename T> \ | |
1638 inline octonion<T> operator op (octonion<T> const & lhs, T const & rhs) \ | |
1639 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1640 | |
1641 #define BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \ | |
1642 template<typename T> \ | |
1643 inline octonion<T> operator op (::std::complex<T> const & lhs, octonion<T> const & rhs) \ | |
1644 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1645 | |
1646 #define BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \ | |
1647 template<typename T> \ | |
1648 inline octonion<T> operator op (octonion<T> const & lhs, ::std::complex<T> const & rhs) \ | |
1649 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1650 | |
1651 #define BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \ | |
1652 template<typename T> \ | |
1653 inline octonion<T> operator op (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) \ | |
1654 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1655 | |
1656 #define BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \ | |
1657 template<typename T> \ | |
1658 inline octonion<T> operator op (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) \ | |
1659 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1660 | |
1661 #define BOOST_OCTONION_OPERATOR_GENERATOR_4(op) \ | |
1662 template<typename T> \ | |
1663 inline octonion<T> operator op (octonion<T> const & lhs, octonion<T> const & rhs) \ | |
1664 BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) | |
1665 | |
1666 #define BOOST_OCTONION_OPERATOR_GENERATOR(op) \ | |
1667 BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \ | |
1668 BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \ | |
1669 BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \ | |
1670 BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \ | |
1671 BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \ | |
1672 BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \ | |
1673 BOOST_OCTONION_OPERATOR_GENERATOR_4(op) | |
1674 | |
1675 | |
1676 BOOST_OCTONION_OPERATOR_GENERATOR(+) | |
1677 BOOST_OCTONION_OPERATOR_GENERATOR(-) | |
1678 BOOST_OCTONION_OPERATOR_GENERATOR(*) | |
1679 BOOST_OCTONION_OPERATOR_GENERATOR(/) | |
1680 | |
1681 | |
1682 #undef BOOST_OCTONION_OPERATOR_GENERATOR | |
1683 | |
1684 #undef BOOST_OCTONION_OPERATOR_GENERATOR_1_L | |
1685 #undef BOOST_OCTONION_OPERATOR_GENERATOR_1_R | |
1686 #undef BOOST_OCTONION_OPERATOR_GENERATOR_2_L | |
1687 #undef BOOST_OCTONION_OPERATOR_GENERATOR_2_R | |
1688 #undef BOOST_OCTONION_OPERATOR_GENERATOR_3_L | |
1689 #undef BOOST_OCTONION_OPERATOR_GENERATOR_3_R | |
1690 #undef BOOST_OCTONION_OPERATOR_GENERATOR_4 | |
1691 | |
1692 #undef BOOST_OCTONION_OPERATOR_GENERATOR_BODY | |
1693 | |
1694 | |
1695 template<typename T> | |
1696 inline octonion<T> operator + (octonion<T> const & o) | |
1697 { | |
1698 return(o); | |
1699 } | |
1700 | |
1701 | |
1702 template<typename T> | |
1703 inline octonion<T> operator - (octonion<T> const & o) | |
1704 { | |
1705 return(octonion<T>(-o.R_component_1(),-o.R_component_2(),-o.R_component_3(),-o.R_component_4(),-o.R_component_5(),-o.R_component_6(),-o.R_component_7(),-o.R_component_8())); | |
1706 } | |
1707 | |
1708 | |
1709 template<typename T> | |
1710 inline bool operator == (T const & lhs, octonion<T> const & rhs) | |
1711 { | |
1712 return( | |
1713 (rhs.R_component_1() == lhs)&& | |
1714 (rhs.R_component_2() == static_cast<T>(0))&& | |
1715 (rhs.R_component_3() == static_cast<T>(0))&& | |
1716 (rhs.R_component_4() == static_cast<T>(0))&& | |
1717 (rhs.R_component_5() == static_cast<T>(0))&& | |
1718 (rhs.R_component_6() == static_cast<T>(0))&& | |
1719 (rhs.R_component_7() == static_cast<T>(0))&& | |
1720 (rhs.R_component_8() == static_cast<T>(0)) | |
1721 ); | |
1722 } | |
1723 | |
1724 | |
1725 template<typename T> | |
1726 inline bool operator == (octonion<T> const & lhs, T const & rhs) | |
1727 { | |
1728 return( | |
1729 (lhs.R_component_1() == rhs)&& | |
1730 (lhs.R_component_2() == static_cast<T>(0))&& | |
1731 (lhs.R_component_3() == static_cast<T>(0))&& | |
1732 (lhs.R_component_4() == static_cast<T>(0))&& | |
1733 (lhs.R_component_5() == static_cast<T>(0))&& | |
1734 (lhs.R_component_6() == static_cast<T>(0))&& | |
1735 (lhs.R_component_7() == static_cast<T>(0))&& | |
1736 (lhs.R_component_8() == static_cast<T>(0)) | |
1737 ); | |
1738 } | |
1739 | |
1740 | |
1741 template<typename T> | |
1742 inline bool operator == (::std::complex<T> const & lhs, octonion<T> const & rhs) | |
1743 { | |
1744 return( | |
1745 (rhs.R_component_1() == lhs.real())&& | |
1746 (rhs.R_component_2() == lhs.imag())&& | |
1747 (rhs.R_component_3() == static_cast<T>(0))&& | |
1748 (rhs.R_component_4() == static_cast<T>(0))&& | |
1749 (rhs.R_component_5() == static_cast<T>(0))&& | |
1750 (rhs.R_component_6() == static_cast<T>(0))&& | |
1751 (rhs.R_component_7() == static_cast<T>(0))&& | |
1752 (rhs.R_component_8() == static_cast<T>(0)) | |
1753 ); | |
1754 } | |
1755 | |
1756 | |
1757 template<typename T> | |
1758 inline bool operator == (octonion<T> const & lhs, ::std::complex<T> const & rhs) | |
1759 { | |
1760 return( | |
1761 (lhs.R_component_1() == rhs.real())&& | |
1762 (lhs.R_component_2() == rhs.imag())&& | |
1763 (lhs.R_component_3() == static_cast<T>(0))&& | |
1764 (lhs.R_component_4() == static_cast<T>(0))&& | |
1765 (lhs.R_component_5() == static_cast<T>(0))&& | |
1766 (lhs.R_component_6() == static_cast<T>(0))&& | |
1767 (lhs.R_component_7() == static_cast<T>(0))&& | |
1768 (lhs.R_component_8() == static_cast<T>(0)) | |
1769 ); | |
1770 } | |
1771 | |
1772 | |
1773 template<typename T> | |
1774 inline bool operator == (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) | |
1775 { | |
1776 return( | |
1777 (rhs.R_component_1() == lhs.R_component_1())&& | |
1778 (rhs.R_component_2() == lhs.R_component_2())&& | |
1779 (rhs.R_component_3() == lhs.R_component_3())&& | |
1780 (rhs.R_component_4() == lhs.R_component_4())&& | |
1781 (rhs.R_component_5() == static_cast<T>(0))&& | |
1782 (rhs.R_component_6() == static_cast<T>(0))&& | |
1783 (rhs.R_component_7() == static_cast<T>(0))&& | |
1784 (rhs.R_component_8() == static_cast<T>(0)) | |
1785 ); | |
1786 } | |
1787 | |
1788 | |
1789 template<typename T> | |
1790 inline bool operator == (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) | |
1791 { | |
1792 return( | |
1793 (lhs.R_component_1() == rhs.R_component_1())&& | |
1794 (lhs.R_component_2() == rhs.R_component_2())&& | |
1795 (lhs.R_component_3() == rhs.R_component_3())&& | |
1796 (lhs.R_component_4() == rhs.R_component_4())&& | |
1797 (lhs.R_component_5() == static_cast<T>(0))&& | |
1798 (lhs.R_component_6() == static_cast<T>(0))&& | |
1799 (lhs.R_component_7() == static_cast<T>(0))&& | |
1800 (lhs.R_component_8() == static_cast<T>(0)) | |
1801 ); | |
1802 } | |
1803 | |
1804 | |
1805 template<typename T> | |
1806 inline bool operator == (octonion<T> const & lhs, octonion<T> const & rhs) | |
1807 { | |
1808 return( | |
1809 (rhs.R_component_1() == lhs.R_component_1())&& | |
1810 (rhs.R_component_2() == lhs.R_component_2())&& | |
1811 (rhs.R_component_3() == lhs.R_component_3())&& | |
1812 (rhs.R_component_4() == lhs.R_component_4())&& | |
1813 (rhs.R_component_5() == lhs.R_component_5())&& | |
1814 (rhs.R_component_6() == lhs.R_component_6())&& | |
1815 (rhs.R_component_7() == lhs.R_component_7())&& | |
1816 (rhs.R_component_8() == lhs.R_component_8()) | |
1817 ); | |
1818 } | |
1819 | |
1820 | |
1821 #define BOOST_OCTONION_NOT_EQUAL_GENERATOR \ | |
1822 { \ | |
1823 return(!(lhs == rhs)); \ | |
1824 } | |
1825 | |
1826 template<typename T> | |
1827 inline bool operator != (T const & lhs, octonion<T> const & rhs) | |
1828 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1829 | |
1830 template<typename T> | |
1831 inline bool operator != (octonion<T> const & lhs, T const & rhs) | |
1832 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1833 | |
1834 template<typename T> | |
1835 inline bool operator != (::std::complex<T> const & lhs, octonion<T> const & rhs) | |
1836 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1837 | |
1838 template<typename T> | |
1839 inline bool operator != (octonion<T> const & lhs, ::std::complex<T> const & rhs) | |
1840 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1841 | |
1842 template<typename T> | |
1843 inline bool operator != (::boost::math::quaternion<T> const & lhs, octonion<T> const & rhs) | |
1844 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1845 | |
1846 template<typename T> | |
1847 inline bool operator != (octonion<T> const & lhs, ::boost::math::quaternion<T> const & rhs) | |
1848 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1849 | |
1850 template<typename T> | |
1851 inline bool operator != (octonion<T> const & lhs, octonion<T> const & rhs) | |
1852 BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1853 | |
1854 #undef BOOST_OCTONION_NOT_EQUAL_GENERATOR | |
1855 | |
1856 | |
1857 // Note: the default values in the constructors of the complex and quaternions make for | |
1858 // a very complex and ambiguous situation; we have made choices to disambiguate. | |
1859 | |
1860 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
1861 template<typename T> | |
1862 ::std::istream & operator >> ( ::std::istream & is, | |
1863 octonion<T>& o) | |
1864 #else | |
1865 template<typename T, typename charT, class traits> | |
1866 ::std::basic_istream<charT,traits> & operator >> ( ::std::basic_istream<charT,traits> & is, | |
1867 octonion<T> & o) | |
1868 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
1869 { | |
1870 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
1871 typedef char charT; | |
1872 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
1873 | |
1874 #ifdef BOOST_NO_STD_LOCALE | |
1875 #else | |
1876 const ::std::ctype<charT> & ct = ::std::use_facet< ::std::ctype<charT> >(is.getloc()); | |
1877 #endif /* BOOST_NO_STD_LOCALE */ | |
1878 | |
1879 T a = T(); | |
1880 T b = T(); | |
1881 T c = T(); | |
1882 T d = T(); | |
1883 T e = T(); | |
1884 T f = T(); | |
1885 T g = T(); | |
1886 T h = T(); | |
1887 | |
1888 ::std::complex<T> u = ::std::complex<T>(); | |
1889 ::std::complex<T> v = ::std::complex<T>(); | |
1890 ::std::complex<T> x = ::std::complex<T>(); | |
1891 ::std::complex<T> y = ::std::complex<T>(); | |
1892 | |
1893 ::boost::math::quaternion<T> p = ::boost::math::quaternion<T>(); | |
1894 ::boost::math::quaternion<T> q = ::boost::math::quaternion<T>(); | |
1895 | |
1896 charT ch = charT(); | |
1897 char cc; | |
1898 | |
1899 is >> ch; // get the first lexeme | |
1900 | |
1901 if (!is.good()) goto finish; | |
1902 | |
1903 #ifdef BOOST_NO_STD_LOCALE | |
1904 cc = ch; | |
1905 #else | |
1906 cc = ct.narrow(ch, char()); | |
1907 #endif /* BOOST_NO_STD_LOCALE */ | |
1908 | |
1909 if (cc == '(') // read "(" | |
1910 { | |
1911 is >> ch; // get the second lexeme | |
1912 | |
1913 if (!is.good()) goto finish; | |
1914 | |
1915 #ifdef BOOST_NO_STD_LOCALE | |
1916 cc = ch; | |
1917 #else | |
1918 cc = ct.narrow(ch, char()); | |
1919 #endif /* BOOST_NO_STD_LOCALE */ | |
1920 | |
1921 if (cc == '(') // read "((" | |
1922 { | |
1923 is >> ch; // get the third lexeme | |
1924 | |
1925 if (!is.good()) goto finish; | |
1926 | |
1927 #ifdef BOOST_NO_STD_LOCALE | |
1928 cc = ch; | |
1929 #else | |
1930 cc = ct.narrow(ch, char()); | |
1931 #endif /* BOOST_NO_STD_LOCALE */ | |
1932 | |
1933 if (cc == '(') // read "(((" | |
1934 { | |
1935 is.putback(ch); | |
1936 | |
1937 is >> u; // read "((u" | |
1938 | |
1939 if (!is.good()) goto finish; | |
1940 | |
1941 is >> ch; // get the next lexeme | |
1942 | |
1943 if (!is.good()) goto finish; | |
1944 | |
1945 #ifdef BOOST_NO_STD_LOCALE | |
1946 cc = ch; | |
1947 #else | |
1948 cc = ct.narrow(ch, char()); | |
1949 #endif /* BOOST_NO_STD_LOCALE */ | |
1950 | |
1951 if (cc == ')') // read "((u)" | |
1952 { | |
1953 is >> ch; // get the next lexeme | |
1954 | |
1955 if (!is.good()) goto finish; | |
1956 | |
1957 #ifdef BOOST_NO_STD_LOCALE | |
1958 cc = ch; | |
1959 #else | |
1960 cc = ct.narrow(ch, char()); | |
1961 #endif /* BOOST_NO_STD_LOCALE */ | |
1962 | |
1963 if (cc == ')') // format: (((a))), (((a,b))) | |
1964 { | |
1965 o = octonion<T>(u); | |
1966 } | |
1967 else if (cc == ',') // read "((u)," | |
1968 { | |
1969 p = ::boost::math::quaternion<T>(u); | |
1970 | |
1971 is >> q; // read "((u),q" | |
1972 | |
1973 if (!is.good()) goto finish; | |
1974 | |
1975 is >> ch; // get the next lexeme | |
1976 | |
1977 if (!is.good()) goto finish; | |
1978 | |
1979 #ifdef BOOST_NO_STD_LOCALE | |
1980 cc = ch; | |
1981 #else | |
1982 cc = ct.narrow(ch, char()); | |
1983 #endif /* BOOST_NO_STD_LOCALE */ | |
1984 | |
1985 if (cc == ')') // format: (((a)),q), (((a,b)),q) | |
1986 { | |
1987 o = octonion<T>(p,q); | |
1988 } | |
1989 else // error | |
1990 { | |
1991 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
1992 is.setstate(::std::ios::failbit); | |
1993 #else | |
1994 is.setstate(::std::ios_base::failbit); | |
1995 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
1996 } | |
1997 } | |
1998 else // error | |
1999 { | |
2000 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2001 is.setstate(::std::ios::failbit); | |
2002 #else | |
2003 is.setstate(::std::ios_base::failbit); | |
2004 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2005 } | |
2006 } | |
2007 else if (cc ==',') // read "((u," | |
2008 { | |
2009 is >> v; // read "((u,v" | |
2010 | |
2011 if (!is.good()) goto finish; | |
2012 | |
2013 is >> ch; // get the next lexeme | |
2014 | |
2015 if (!is.good()) goto finish; | |
2016 | |
2017 #ifdef BOOST_NO_STD_LOCALE | |
2018 cc = ch; | |
2019 #else | |
2020 cc = ct.narrow(ch, char()); | |
2021 #endif /* BOOST_NO_STD_LOCALE */ | |
2022 | |
2023 if (cc == ')') // read "((u,v)" | |
2024 { | |
2025 p = ::boost::math::quaternion<T>(u,v); | |
2026 | |
2027 is >> ch; // get the next lexeme | |
2028 | |
2029 if (!is.good()) goto finish; | |
2030 | |
2031 #ifdef BOOST_NO_STD_LOCALE | |
2032 cc = ch; | |
2033 #else | |
2034 cc = ct.narrow(ch, char()); | |
2035 #endif /* BOOST_NO_STD_LOCALE */ | |
2036 | |
2037 if (cc == ')') // format: (((a),v)), (((a,b),v)) | |
2038 { | |
2039 o = octonion<T>(p); | |
2040 } | |
2041 else if (cc == ',') // read "((u,v)," | |
2042 { | |
2043 is >> q; // read "(p,q" | |
2044 | |
2045 if (!is.good()) goto finish; | |
2046 | |
2047 is >> ch; // get the next lexeme | |
2048 | |
2049 if (!is.good()) goto finish; | |
2050 | |
2051 #ifdef BOOST_NO_STD_LOCALE | |
2052 cc = ch; | |
2053 #else | |
2054 cc = ct.narrow(ch, char()); | |
2055 #endif /* BOOST_NO_STD_LOCALE */ | |
2056 | |
2057 if (cc == ')') // format: (((a),v),q), (((a,b),v),q) | |
2058 { | |
2059 o = octonion<T>(p,q); | |
2060 } | |
2061 else // error | |
2062 { | |
2063 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2064 is.setstate(::std::ios::failbit); | |
2065 #else | |
2066 is.setstate(::std::ios_base::failbit); | |
2067 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2068 } | |
2069 } | |
2070 else // error | |
2071 { | |
2072 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2073 is.setstate(::std::ios::failbit); | |
2074 #else | |
2075 is.setstate(::std::ios_base::failbit); | |
2076 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2077 } | |
2078 } | |
2079 else // error | |
2080 { | |
2081 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2082 is.setstate(::std::ios::failbit); | |
2083 #else | |
2084 is.setstate(::std::ios_base::failbit); | |
2085 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2086 } | |
2087 } | |
2088 else // error | |
2089 { | |
2090 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2091 is.setstate(::std::ios::failbit); | |
2092 #else | |
2093 is.setstate(::std::ios_base::failbit); | |
2094 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2095 } | |
2096 } | |
2097 else // read "((a" | |
2098 { | |
2099 is.putback(ch); | |
2100 | |
2101 is >> a; // we extract the first component | |
2102 | |
2103 if (!is.good()) goto finish; | |
2104 | |
2105 is >> ch; // get the next lexeme | |
2106 | |
2107 if (!is.good()) goto finish; | |
2108 | |
2109 #ifdef BOOST_NO_STD_LOCALE | |
2110 cc = ch; | |
2111 #else | |
2112 cc = ct.narrow(ch, char()); | |
2113 #endif /* BOOST_NO_STD_LOCALE */ | |
2114 | |
2115 if (cc == ')') // read "((a)" | |
2116 { | |
2117 is >> ch; // get the next lexeme | |
2118 | |
2119 if (!is.good()) goto finish; | |
2120 | |
2121 #ifdef BOOST_NO_STD_LOCALE | |
2122 cc = ch; | |
2123 #else | |
2124 cc = ct.narrow(ch, char()); | |
2125 #endif /* BOOST_NO_STD_LOCALE */ | |
2126 | |
2127 if (cc == ')') // read "((a))" | |
2128 { | |
2129 o = octonion<T>(a); | |
2130 } | |
2131 else if (cc == ',') // read "((a)," | |
2132 { | |
2133 is >> ch; // get the next lexeme | |
2134 | |
2135 if (!is.good()) goto finish; | |
2136 | |
2137 #ifdef BOOST_NO_STD_LOCALE | |
2138 cc = ch; | |
2139 #else | |
2140 cc = ct.narrow(ch, char()); | |
2141 #endif /* BOOST_NO_STD_LOCALE */ | |
2142 | |
2143 if (cc == '(') // read "((a),(" | |
2144 { | |
2145 is >> ch; // get the next lexeme | |
2146 | |
2147 if (!is.good()) goto finish; | |
2148 | |
2149 #ifdef BOOST_NO_STD_LOCALE | |
2150 cc = ch; | |
2151 #else | |
2152 cc = ct.narrow(ch, char()); | |
2153 #endif /* BOOST_NO_STD_LOCALE */ | |
2154 | |
2155 if (cc == '(') // read "((a),((" | |
2156 { | |
2157 is.putback(ch); | |
2158 | |
2159 is.putback(ch); // we backtrack twice, with the same value! | |
2160 | |
2161 is >> q; // read "((a),q" | |
2162 | |
2163 if (!is.good()) goto finish; | |
2164 | |
2165 is >> ch; // get the next lexeme | |
2166 | |
2167 if (!is.good()) goto finish; | |
2168 | |
2169 #ifdef BOOST_NO_STD_LOCALE | |
2170 cc = ch; | |
2171 #else | |
2172 cc = ct.narrow(ch, char()); | |
2173 #endif /* BOOST_NO_STD_LOCALE */ | |
2174 | |
2175 if (cc == ')') // read "((a),q)" | |
2176 { | |
2177 p = ::boost::math::quaternion<T>(a); | |
2178 | |
2179 o = octonion<T>(p,q); | |
2180 } | |
2181 else // error | |
2182 { | |
2183 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2184 is.setstate(::std::ios::failbit); | |
2185 #else | |
2186 is.setstate(::std::ios_base::failbit); | |
2187 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2188 } | |
2189 } | |
2190 else // read "((a),(c" or "((a),(e" | |
2191 { | |
2192 is.putback(ch); | |
2193 | |
2194 is >> c; | |
2195 | |
2196 if (!is.good()) goto finish; | |
2197 | |
2198 is >> ch; // get the next lexeme | |
2199 | |
2200 if (!is.good()) goto finish; | |
2201 | |
2202 #ifdef BOOST_NO_STD_LOCALE | |
2203 cc = ch; | |
2204 #else | |
2205 cc = ct.narrow(ch, char()); | |
2206 #endif /* BOOST_NO_STD_LOCALE */ | |
2207 | |
2208 if (cc == ')') // read "((a),(c)" (ambiguity resolution) | |
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))" | |
2221 { | |
2222 o = octonion<T>(a,b,c); | |
2223 } | |
2224 else if (cc == ',') // read "((a),(c)," | |
2225 { | |
2226 u = ::std::complex<T>(a); | |
2227 | |
2228 v = ::std::complex<T>(c); | |
2229 | |
2230 is >> x; // read "((a),(c),x" | |
2231 | |
2232 if (!is.good()) goto finish; | |
2233 | |
2234 is >> ch; // get the next lexeme | |
2235 | |
2236 if (!is.good()) goto finish; | |
2237 | |
2238 #ifdef BOOST_NO_STD_LOCALE | |
2239 cc = ch; | |
2240 #else | |
2241 cc = ct.narrow(ch, char()); | |
2242 #endif /* BOOST_NO_STD_LOCALE */ | |
2243 | |
2244 if (cc == ')') // read "((a),(c),x)" | |
2245 { | |
2246 o = octonion<T>(u,v,x); | |
2247 } | |
2248 else if (cc == ',') // read "((a),(c),x," | |
2249 { | |
2250 is >> y; // read "((a),(c),x,y" | |
2251 | |
2252 if (!is.good()) goto finish; | |
2253 | |
2254 is >> ch; // get the next lexeme | |
2255 | |
2256 if (!is.good()) goto finish; | |
2257 | |
2258 #ifdef BOOST_NO_STD_LOCALE | |
2259 cc = ch; | |
2260 #else | |
2261 cc = ct.narrow(ch, char()); | |
2262 #endif /* BOOST_NO_STD_LOCALE */ | |
2263 | |
2264 if (cc == ')') // read "((a),(c),x,y)" | |
2265 { | |
2266 o = octonion<T>(u,v,x,y); | |
2267 } | |
2268 else // error | |
2269 { | |
2270 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2271 is.setstate(::std::ios::failbit); | |
2272 #else | |
2273 is.setstate(::std::ios_base::failbit); | |
2274 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2275 } | |
2276 } | |
2277 else // error | |
2278 { | |
2279 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2280 is.setstate(::std::ios::failbit); | |
2281 #else | |
2282 is.setstate(::std::ios_base::failbit); | |
2283 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2284 } | |
2285 } | |
2286 else // error | |
2287 { | |
2288 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2289 is.setstate(::std::ios::failbit); | |
2290 #else | |
2291 is.setstate(::std::ios_base::failbit); | |
2292 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2293 } | |
2294 } | |
2295 else if (cc == ',') // read "((a),(c," or "((a),(e," | |
2296 { | |
2297 is >> ch; // get the next lexeme | |
2298 | |
2299 if (!is.good()) goto finish; | |
2300 | |
2301 #ifdef BOOST_NO_STD_LOCALE | |
2302 cc = ch; | |
2303 #else | |
2304 cc = ct.narrow(ch, char()); | |
2305 #endif /* BOOST_NO_STD_LOCALE */ | |
2306 | |
2307 if (cc == '(') // read "((a),(e,(" (ambiguity resolution) | |
2308 { | |
2309 p = ::boost::math::quaternion<T>(a); | |
2310 | |
2311 x = ::std::complex<T>(c); // "c" was actually "e" | |
2312 | |
2313 is.putback(ch); // we can only backtrace once | |
2314 | |
2315 is >> y; // read "((a),(e,y" | |
2316 | |
2317 if (!is.good()) goto finish; | |
2318 | |
2319 is >> ch; // get the next lexeme | |
2320 | |
2321 #ifdef BOOST_NO_STD_LOCALE | |
2322 cc = ch; | |
2323 #else | |
2324 cc = ct.narrow(ch, char()); | |
2325 #endif /* BOOST_NO_STD_LOCALE */ | |
2326 | |
2327 if (cc == ')') // read "((a),(e,y)" | |
2328 { | |
2329 q = ::boost::math::quaternion<T>(x,y); | |
2330 | |
2331 is >> ch; // get the next lexeme | |
2332 | |
2333 #ifdef BOOST_NO_STD_LOCALE | |
2334 cc = ch; | |
2335 #else | |
2336 cc = ct.narrow(ch, char()); | |
2337 #endif /* BOOST_NO_STD_LOCALE */ | |
2338 | |
2339 if (cc == ')') // read "((a),(e,y))" | |
2340 { | |
2341 o = octonion<T>(p,q); | |
2342 } | |
2343 else // error | |
2344 { | |
2345 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2346 is.setstate(::std::ios::failbit); | |
2347 #else | |
2348 is.setstate(::std::ios_base::failbit); | |
2349 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2350 } | |
2351 } | |
2352 else // error | |
2353 { | |
2354 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2355 is.setstate(::std::ios::failbit); | |
2356 #else | |
2357 is.setstate(::std::ios_base::failbit); | |
2358 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2359 } | |
2360 } | |
2361 else // read "((a),(c,d" or "((a),(e,f" | |
2362 { | |
2363 is.putback(ch); | |
2364 | |
2365 is >> d; | |
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,d)" (ambiguity resolution) | |
2380 { | |
2381 is >> ch; // get the next lexeme | |
2382 | |
2383 if (!is.good()) goto finish; | |
2384 | |
2385 #ifdef BOOST_NO_STD_LOCALE | |
2386 cc = ch; | |
2387 #else | |
2388 cc = ct.narrow(ch, char()); | |
2389 #endif /* BOOST_NO_STD_LOCALE */ | |
2390 | |
2391 if (cc == ')') // read "((a),(c,d))" | |
2392 { | |
2393 o = octonion<T>(a,b,c,d); | |
2394 } | |
2395 else if (cc == ',') // read "((a),(c,d)," | |
2396 { | |
2397 u = ::std::complex<T>(a); | |
2398 | |
2399 v = ::std::complex<T>(c,d); | |
2400 | |
2401 is >> x; // read "((a),(c,d),x" | |
2402 | |
2403 if (!is.good()) goto finish; | |
2404 | |
2405 is >> ch; // get the next lexeme | |
2406 | |
2407 if (!is.good()) goto finish; | |
2408 | |
2409 #ifdef BOOST_NO_STD_LOCALE | |
2410 cc = ch; | |
2411 #else | |
2412 cc = ct.narrow(ch, char()); | |
2413 #endif /* BOOST_NO_STD_LOCALE */ | |
2414 | |
2415 if (cc == ')') // read "((a),(c,d),x)" | |
2416 { | |
2417 o = octonion<T>(u,v,x); | |
2418 } | |
2419 else if (cc == ',') // read "((a),(c,d),x," | |
2420 { | |
2421 is >> y; // read "((a),(c,d),x,y" | |
2422 | |
2423 if (!is.good()) goto finish; | |
2424 | |
2425 is >> ch; // get the next lexeme | |
2426 | |
2427 if (!is.good()) goto finish; | |
2428 | |
2429 #ifdef BOOST_NO_STD_LOCALE | |
2430 cc = ch; | |
2431 #else | |
2432 cc = ct.narrow(ch, char()); | |
2433 #endif /* BOOST_NO_STD_LOCALE */ | |
2434 | |
2435 if (cc == ')') // read "((a),(c,d),x,y)" | |
2436 { | |
2437 o = octonion<T>(u,v,x,y); | |
2438 } | |
2439 else // error | |
2440 { | |
2441 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2442 is.setstate(::std::ios::failbit); | |
2443 #else | |
2444 is.setstate(::std::ios_base::failbit); | |
2445 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2446 } | |
2447 } | |
2448 else // error | |
2449 { | |
2450 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2451 is.setstate(::std::ios::failbit); | |
2452 #else | |
2453 is.setstate(::std::ios_base::failbit); | |
2454 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2455 } | |
2456 } | |
2457 else // error | |
2458 { | |
2459 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2460 is.setstate(::std::ios::failbit); | |
2461 #else | |
2462 is.setstate(::std::ios_base::failbit); | |
2463 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2464 } | |
2465 } | |
2466 else if (cc == ',') // read "((a),(e,f," (ambiguity resolution) | |
2467 { | |
2468 p = ::boost::math::quaternion<T>(a); | |
2469 | |
2470 is >> g; // read "((a),(e,f,g" (too late to backtrack) | |
2471 | |
2472 if (!is.good()) goto finish; | |
2473 | |
2474 is >> ch; // get the next lexeme | |
2475 | |
2476 if (!is.good()) goto finish; | |
2477 | |
2478 #ifdef BOOST_NO_STD_LOCALE | |
2479 cc = ch; | |
2480 #else | |
2481 cc = ct.narrow(ch, char()); | |
2482 #endif /* BOOST_NO_STD_LOCALE */ | |
2483 | |
2484 if (cc == ')') // read "((a),(e,f,g)" | |
2485 { | |
2486 q = ::boost::math::quaternion<T>(c,d,g); // "c" was actually "e", and "d" was actually "f" | |
2487 | |
2488 is >> ch; // get the next lexeme | |
2489 | |
2490 if (!is.good()) goto finish; | |
2491 | |
2492 #ifdef BOOST_NO_STD_LOCALE | |
2493 cc = ch; | |
2494 #else | |
2495 cc = ct.narrow(ch, char()); | |
2496 #endif /* BOOST_NO_STD_LOCALE */ | |
2497 | |
2498 if (cc == ')') // read "((a),(e,f,g))" | |
2499 { | |
2500 o = octonion<T>(p,q); | |
2501 } | |
2502 else // error | |
2503 { | |
2504 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2505 is.setstate(::std::ios::failbit); | |
2506 #else | |
2507 is.setstate(::std::ios_base::failbit); | |
2508 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2509 } | |
2510 } | |
2511 else if (cc == ',') // read "((a),(e,f,g," | |
2512 { | |
2513 is >> h; // read "((a),(e,f,g,h" | |
2514 | |
2515 if (!is.good()) goto finish; | |
2516 | |
2517 is >> ch; // get the next lexeme | |
2518 | |
2519 if (!is.good()) goto finish; | |
2520 | |
2521 #ifdef BOOST_NO_STD_LOCALE | |
2522 cc = ch; | |
2523 #else | |
2524 cc = ct.narrow(ch, char()); | |
2525 #endif /* BOOST_NO_STD_LOCALE */ | |
2526 | |
2527 if (cc == ')') // read "((a),(e,f,g,h)" | |
2528 { | |
2529 q = ::boost::math::quaternion<T>(c,d,g,h); // "c" was actually "e", and "d" was actually "f" | |
2530 | |
2531 is >> ch; // get the next lexeme | |
2532 | |
2533 if (!is.good()) goto finish; | |
2534 | |
2535 #ifdef BOOST_NO_STD_LOCALE | |
2536 cc = ch; | |
2537 #else | |
2538 cc = ct.narrow(ch, char()); | |
2539 #endif /* BOOST_NO_STD_LOCALE */ | |
2540 | |
2541 if (cc == ')') // read "((a),(e,f,g,h))" | |
2542 { | |
2543 o = octonion<T>(p,q); | |
2544 } | |
2545 else // error | |
2546 { | |
2547 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2548 is.setstate(::std::ios::failbit); | |
2549 #else | |
2550 is.setstate(::std::ios_base::failbit); | |
2551 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2552 } | |
2553 } | |
2554 else // error | |
2555 { | |
2556 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2557 is.setstate(::std::ios::failbit); | |
2558 #else | |
2559 is.setstate(::std::ios_base::failbit); | |
2560 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2561 } | |
2562 } | |
2563 else // error | |
2564 { | |
2565 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2566 is.setstate(::std::ios::failbit); | |
2567 #else | |
2568 is.setstate(::std::ios_base::failbit); | |
2569 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2570 } | |
2571 } | |
2572 else // error | |
2573 { | |
2574 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2575 is.setstate(::std::ios::failbit); | |
2576 #else | |
2577 is.setstate(::std::ios_base::failbit); | |
2578 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2579 } | |
2580 } | |
2581 } | |
2582 else // error | |
2583 { | |
2584 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2585 is.setstate(::std::ios::failbit); | |
2586 #else | |
2587 is.setstate(::std::ios_base::failbit); | |
2588 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2589 } | |
2590 } | |
2591 } | |
2592 else // read "((a),c" (ambiguity resolution) | |
2593 { | |
2594 is.putback(ch); | |
2595 | |
2596 is >> c; // we extract the third component | |
2597 | |
2598 if (!is.good()) goto finish; | |
2599 | |
2600 is >> ch; // get the next lexeme | |
2601 | |
2602 if (!is.good()) goto finish; | |
2603 | |
2604 #ifdef BOOST_NO_STD_LOCALE | |
2605 cc = ch; | |
2606 #else | |
2607 cc = ct.narrow(ch, char()); | |
2608 #endif /* BOOST_NO_STD_LOCALE */ | |
2609 | |
2610 if (cc == ')') // read "((a),c)" | |
2611 { | |
2612 o = octonion<T>(a,b,c); | |
2613 } | |
2614 else if (cc == ',') // read "((a),c," | |
2615 { | |
2616 is >> x; // read "((a),c,x" | |
2617 | |
2618 if (!is.good()) goto finish; | |
2619 | |
2620 is >> ch; // get the next lexeme | |
2621 | |
2622 if (!is.good()) goto finish; | |
2623 | |
2624 #ifdef BOOST_NO_STD_LOCALE | |
2625 cc = ch; | |
2626 #else | |
2627 cc = ct.narrow(ch, char()); | |
2628 #endif /* BOOST_NO_STD_LOCALE */ | |
2629 | |
2630 if (cc == ')') // read "((a),c,x)" | |
2631 { | |
2632 o = octonion<T>(a,b,c,d,x.real(),x.imag()); | |
2633 } | |
2634 else if (cc == ',') // read "((a),c,x," | |
2635 { | |
2636 is >> y;if (!is.good()) goto finish; // read "((a),c,x,y" | |
2637 | |
2638 is >> ch; // get the next lexeme | |
2639 | |
2640 if (!is.good()) goto finish; | |
2641 | |
2642 #ifdef BOOST_NO_STD_LOCALE | |
2643 cc = ch; | |
2644 #else | |
2645 cc = ct.narrow(ch, char()); | |
2646 #endif /* BOOST_NO_STD_LOCALE */ | |
2647 | |
2648 if (cc == ')') // read "((a),c,x,y)" | |
2649 { | |
2650 o = octonion<T>(a,b,c,d,x.real(),x.imag(),y.real(),y.imag()); | |
2651 } | |
2652 else // error | |
2653 { | |
2654 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2655 is.setstate(::std::ios::failbit); | |
2656 #else | |
2657 is.setstate(::std::ios_base::failbit); | |
2658 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2659 } | |
2660 } | |
2661 else // error | |
2662 { | |
2663 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2664 is.setstate(::std::ios::failbit); | |
2665 #else | |
2666 is.setstate(::std::ios_base::failbit); | |
2667 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2668 } | |
2669 } | |
2670 else // error | |
2671 { | |
2672 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2673 is.setstate(::std::ios::failbit); | |
2674 #else | |
2675 is.setstate(::std::ios_base::failbit); | |
2676 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2677 } | |
2678 } | |
2679 } | |
2680 else // error | |
2681 { | |
2682 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2683 is.setstate(::std::ios::failbit); | |
2684 #else | |
2685 is.setstate(::std::ios_base::failbit); | |
2686 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2687 } | |
2688 } | |
2689 else if (cc ==',') // read "((a," | |
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,(" | |
2702 { | |
2703 u = ::std::complex<T>(a); | |
2704 | |
2705 is.putback(ch); // can only backtrack so much | |
2706 | |
2707 is >> v; // read "((a,v" | |
2708 | |
2709 if (!is.good()) goto finish; | |
2710 | |
2711 is >> ch; // get the next lexeme | |
2712 | |
2713 if (!is.good()) goto finish; | |
2714 | |
2715 #ifdef BOOST_NO_STD_LOCALE | |
2716 cc = ch; | |
2717 #else | |
2718 cc = ct.narrow(ch, char()); | |
2719 #endif /* BOOST_NO_STD_LOCALE */ | |
2720 | |
2721 if (cc == ')') // read "((a,v)" | |
2722 { | |
2723 is >> ch; // get the next lexeme | |
2724 | |
2725 if (!is.good()) goto finish; | |
2726 | |
2727 #ifdef BOOST_NO_STD_LOCALE | |
2728 cc = ch; | |
2729 #else | |
2730 cc = ct.narrow(ch, char()); | |
2731 #endif /* BOOST_NO_STD_LOCALE */ | |
2732 | |
2733 if (cc == ')') // read "((a,v))" | |
2734 { | |
2735 o = octonion<T>(u,v); | |
2736 } | |
2737 else if (cc == ',') // read "((a,v)," | |
2738 { | |
2739 p = ::boost::math::quaternion<T>(u,v); | |
2740 | |
2741 is >> q; // read "((a,v),q" | |
2742 | |
2743 if (!is.good()) goto finish; | |
2744 | |
2745 is >> ch; // get the next lexeme | |
2746 | |
2747 if (!is.good()) goto finish; | |
2748 | |
2749 #ifdef BOOST_NO_STD_LOCALE | |
2750 cc = ch; | |
2751 #else | |
2752 cc = ct.narrow(ch, char()); | |
2753 #endif /* BOOST_NO_STD_LOCALE */ | |
2754 | |
2755 if (cc == ')') // read "((a,v),q)" | |
2756 { | |
2757 o = octonion<T>(p,q); | |
2758 } | |
2759 else // error | |
2760 { | |
2761 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2762 is.setstate(::std::ios::failbit); | |
2763 #else | |
2764 is.setstate(::std::ios_base::failbit); | |
2765 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2766 } | |
2767 } | |
2768 else // error | |
2769 { | |
2770 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2771 is.setstate(::std::ios::failbit); | |
2772 #else | |
2773 is.setstate(::std::ios_base::failbit); | |
2774 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2775 } | |
2776 } | |
2777 else // error | |
2778 { | |
2779 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2780 is.setstate(::std::ios::failbit); | |
2781 #else | |
2782 is.setstate(::std::ios_base::failbit); | |
2783 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2784 } | |
2785 } | |
2786 else | |
2787 { | |
2788 is.putback(ch); | |
2789 | |
2790 is >> b; // read "((a,b" | |
2791 | |
2792 if (!is.good()) goto finish; | |
2793 | |
2794 is >> ch; // get the next lexeme | |
2795 | |
2796 if (!is.good()) goto finish; | |
2797 | |
2798 #ifdef BOOST_NO_STD_LOCALE | |
2799 cc = ch; | |
2800 #else | |
2801 cc = ct.narrow(ch, char()); | |
2802 #endif /* BOOST_NO_STD_LOCALE */ | |
2803 | |
2804 if (cc == ')') // read "((a,b)" | |
2805 { | |
2806 is >> ch; // get the next lexeme | |
2807 | |
2808 if (!is.good()) goto finish; | |
2809 | |
2810 #ifdef BOOST_NO_STD_LOCALE | |
2811 cc = ch; | |
2812 #else | |
2813 cc = ct.narrow(ch, char()); | |
2814 #endif /* BOOST_NO_STD_LOCALE */ | |
2815 | |
2816 if (cc == ')') // read "((a,b))" | |
2817 { | |
2818 o = octonion<T>(a,b); | |
2819 } | |
2820 else if (cc == ',') // read "((a,b)," | |
2821 { | |
2822 is >> ch; // get the next lexeme | |
2823 | |
2824 if (!is.good()) goto finish; | |
2825 | |
2826 #ifdef BOOST_NO_STD_LOCALE | |
2827 cc = ch; | |
2828 #else | |
2829 cc = ct.narrow(ch, char()); | |
2830 #endif /* BOOST_NO_STD_LOCALE */ | |
2831 | |
2832 if (cc == '(') // read "((a,b),(" | |
2833 { | |
2834 is >> ch; // get the next lexeme | |
2835 | |
2836 if (!is.good()) goto finish; | |
2837 | |
2838 #ifdef BOOST_NO_STD_LOCALE | |
2839 cc = ch; | |
2840 #else | |
2841 cc = ct.narrow(ch, char()); | |
2842 #endif /* BOOST_NO_STD_LOCALE */ | |
2843 | |
2844 if (cc == '(') // read "((a,b),((" | |
2845 { | |
2846 p = ::boost::math::quaternion<T>(a,b); | |
2847 | |
2848 is.putback(ch); | |
2849 | |
2850 is.putback(ch); // we backtrack twice, with the same value | |
2851 | |
2852 is >> q; // read "((a,b),q" | |
2853 | |
2854 if (!is.good()) goto finish; | |
2855 | |
2856 is >> ch; // get the next lexeme | |
2857 | |
2858 if (!is.good()) goto finish; | |
2859 | |
2860 #ifdef BOOST_NO_STD_LOCALE | |
2861 cc = ch; | |
2862 #else | |
2863 cc = ct.narrow(ch, char()); | |
2864 #endif /* BOOST_NO_STD_LOCALE */ | |
2865 | |
2866 if (cc == ')') // read "((a,b),q)" | |
2867 { | |
2868 o = octonion<T>(p,q); | |
2869 } | |
2870 else // error | |
2871 { | |
2872 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2873 is.setstate(::std::ios::failbit); | |
2874 #else | |
2875 is.setstate(::std::ios_base::failbit); | |
2876 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2877 } | |
2878 } | |
2879 else // read "((a,b),(c" or "((a,b),(e" | |
2880 { | |
2881 is.putback(ch); | |
2882 | |
2883 is >> c; | |
2884 | |
2885 if (!is.good()) goto finish; | |
2886 | |
2887 is >> ch; // get the next lexeme | |
2888 | |
2889 if (!is.good()) goto finish; | |
2890 | |
2891 #ifdef BOOST_NO_STD_LOCALE | |
2892 cc = ch; | |
2893 #else | |
2894 cc = ct.narrow(ch, char()); | |
2895 #endif /* BOOST_NO_STD_LOCALE */ | |
2896 | |
2897 if (cc == ')') // read "((a,b),(c)" (ambiguity resolution) | |
2898 { | |
2899 is >> ch; // get the next lexeme | |
2900 | |
2901 if (!is.good()) goto finish; | |
2902 | |
2903 #ifdef BOOST_NO_STD_LOCALE | |
2904 cc = ch; | |
2905 #else | |
2906 cc = ct.narrow(ch, char()); | |
2907 #endif /* BOOST_NO_STD_LOCALE */ | |
2908 | |
2909 if (cc == ')') // read "((a,b),(c))" | |
2910 { | |
2911 o = octonion<T>(a,b,c); | |
2912 } | |
2913 else if (cc == ',') // read "((a,b),(c)," | |
2914 { | |
2915 u = ::std::complex<T>(a,b); | |
2916 | |
2917 v = ::std::complex<T>(c); | |
2918 | |
2919 is >> x; // read "((a,b),(c),x" | |
2920 | |
2921 if (!is.good()) goto finish; | |
2922 | |
2923 is >> ch; // get the next lexeme | |
2924 | |
2925 if (!is.good()) goto finish; | |
2926 | |
2927 #ifdef BOOST_NO_STD_LOCALE | |
2928 cc = ch; | |
2929 #else | |
2930 cc = ct.narrow(ch, char()); | |
2931 #endif /* BOOST_NO_STD_LOCALE */ | |
2932 | |
2933 if (cc == ')') // read "((a,b),(c),x)" | |
2934 { | |
2935 o = octonion<T>(u,v,x); | |
2936 } | |
2937 else if (cc == ',') // read "((a,b),(c),x," | |
2938 { | |
2939 is >> y; // read "((a,b),(c),x,y" | |
2940 | |
2941 if (!is.good()) goto finish; | |
2942 | |
2943 is >> ch; // get the next lexeme | |
2944 | |
2945 if (!is.good()) goto finish; | |
2946 | |
2947 #ifdef BOOST_NO_STD_LOCALE | |
2948 cc = ch; | |
2949 #else | |
2950 cc = ct.narrow(ch, char()); | |
2951 #endif /* BOOST_NO_STD_LOCALE */ | |
2952 | |
2953 if (cc == ')') // read "((a,b),(c),x,y)" | |
2954 { | |
2955 o = octonion<T>(u,v,x,y); | |
2956 } | |
2957 else // error | |
2958 { | |
2959 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2960 is.setstate(::std::ios::failbit); | |
2961 #else | |
2962 is.setstate(::std::ios_base::failbit); | |
2963 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2964 } | |
2965 } | |
2966 else // error | |
2967 { | |
2968 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2969 is.setstate(::std::ios::failbit); | |
2970 #else | |
2971 is.setstate(::std::ios_base::failbit); | |
2972 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2973 } | |
2974 } | |
2975 else // error | |
2976 { | |
2977 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
2978 is.setstate(::std::ios::failbit); | |
2979 #else | |
2980 is.setstate(::std::ios_base::failbit); | |
2981 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
2982 } | |
2983 } | |
2984 else if (cc == ',') // read "((a,b),(c," or "((a,b),(e," | |
2985 { | |
2986 is >> ch; // get the next lexeme | |
2987 | |
2988 if (!is.good()) goto finish; | |
2989 | |
2990 #ifdef BOOST_NO_STD_LOCALE | |
2991 cc = ch; | |
2992 #else | |
2993 cc = ct.narrow(ch, char()); | |
2994 #endif /* BOOST_NO_STD_LOCALE */ | |
2995 | |
2996 if (cc == '(') // read "((a,b),(e,(" (ambiguity resolution) | |
2997 { | |
2998 u = ::std::complex<T>(a,b); | |
2999 | |
3000 x = ::std::complex<T>(c); // "c" is actually "e" | |
3001 | |
3002 is.putback(ch); | |
3003 | |
3004 is >> y; // read "((a,b),(e,y" | |
3005 | |
3006 if (!is.good()) goto finish; | |
3007 | |
3008 is >> ch; // get the next lexeme | |
3009 | |
3010 if (!is.good()) goto finish; | |
3011 | |
3012 #ifdef BOOST_NO_STD_LOCALE | |
3013 cc = ch; | |
3014 #else | |
3015 cc = ct.narrow(ch, char()); | |
3016 #endif /* BOOST_NO_STD_LOCALE */ | |
3017 | |
3018 if (cc == ')') // read "((a,b),(e,y)" | |
3019 { | |
3020 is >> ch; // get the next lexeme | |
3021 | |
3022 if (!is.good()) goto finish; | |
3023 | |
3024 #ifdef BOOST_NO_STD_LOCALE | |
3025 cc = ch; | |
3026 #else | |
3027 cc = ct.narrow(ch, char()); | |
3028 #endif /* BOOST_NO_STD_LOCALE */ | |
3029 | |
3030 if (cc == ')') // read "((a,b),(e,y))" | |
3031 { | |
3032 o = octonion<T>(u,v,x,y); | |
3033 } | |
3034 else // error | |
3035 { | |
3036 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3037 is.setstate(::std::ios::failbit); | |
3038 #else | |
3039 is.setstate(::std::ios_base::failbit); | |
3040 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3041 } | |
3042 } | |
3043 else // error | |
3044 { | |
3045 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3046 is.setstate(::std::ios::failbit); | |
3047 #else | |
3048 is.setstate(::std::ios_base::failbit); | |
3049 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3050 } | |
3051 } | |
3052 else // read "((a,b),(c,d" or "((a,b),(e,f" | |
3053 { | |
3054 is.putback(ch); | |
3055 | |
3056 is >> d; | |
3057 | |
3058 if (!is.good()) goto finish; | |
3059 | |
3060 is >> ch; // get the next lexeme | |
3061 | |
3062 if (!is.good()) goto finish; | |
3063 | |
3064 #ifdef BOOST_NO_STD_LOCALE | |
3065 cc = ch; | |
3066 #else | |
3067 cc = ct.narrow(ch, char()); | |
3068 #endif /* BOOST_NO_STD_LOCALE */ | |
3069 | |
3070 if (cc == ')') // read "((a,b),(c,d)" (ambiguity resolution) | |
3071 { | |
3072 u = ::std::complex<T>(a,b); | |
3073 | |
3074 v = ::std::complex<T>(c,d); | |
3075 | |
3076 is >> ch; // get the next lexeme | |
3077 | |
3078 if (!is.good()) goto finish; | |
3079 | |
3080 #ifdef BOOST_NO_STD_LOCALE | |
3081 cc = ch; | |
3082 #else | |
3083 cc = ct.narrow(ch, char()); | |
3084 #endif /* BOOST_NO_STD_LOCALE */ | |
3085 | |
3086 if (cc == ')') // read "((a,b),(c,d))" | |
3087 { | |
3088 o = octonion<T>(u,v); | |
3089 } | |
3090 else if (cc == ',') // read "((a,b),(c,d)," | |
3091 { | |
3092 is >> x; // read "((a,b),(c,d),x | |
3093 | |
3094 if (!is.good()) goto finish; | |
3095 | |
3096 is >> ch; // get the next lexeme | |
3097 | |
3098 if (!is.good()) goto finish; | |
3099 | |
3100 #ifdef BOOST_NO_STD_LOCALE | |
3101 cc = ch; | |
3102 #else | |
3103 cc = ct.narrow(ch, char()); | |
3104 #endif /* BOOST_NO_STD_LOCALE */ | |
3105 | |
3106 if (cc == ')') // read "((a,b),(c,d),x)" | |
3107 { | |
3108 o = octonion<T>(u,v,x); | |
3109 } | |
3110 else if (cc == ',') // read "((a,b),(c,d),x," | |
3111 { | |
3112 is >> y; // read "((a,b),(c,d),x,y" | |
3113 | |
3114 if (!is.good()) goto finish; | |
3115 | |
3116 is >> ch; // get the next lexeme | |
3117 | |
3118 if (!is.good()) goto finish; | |
3119 | |
3120 #ifdef BOOST_NO_STD_LOCALE | |
3121 cc = ch; | |
3122 #else | |
3123 cc = ct.narrow(ch, char()); | |
3124 #endif /* BOOST_NO_STD_LOCALE */ | |
3125 | |
3126 if (cc == ')') // read "((a,b),(c,d),x,y)" | |
3127 { | |
3128 o = octonion<T>(u,v,x,y); | |
3129 } | |
3130 else // error | |
3131 { | |
3132 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3133 is.setstate(::std::ios::failbit); | |
3134 #else | |
3135 is.setstate(::std::ios_base::failbit); | |
3136 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3137 } | |
3138 } | |
3139 else // error | |
3140 { | |
3141 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3142 is.setstate(::std::ios::failbit); | |
3143 #else | |
3144 is.setstate(::std::ios_base::failbit); | |
3145 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3146 } | |
3147 } | |
3148 else // error | |
3149 { | |
3150 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3151 is.setstate(::std::ios::failbit); | |
3152 #else | |
3153 is.setstate(::std::ios_base::failbit); | |
3154 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3155 } | |
3156 } | |
3157 else if (cc == ',') // read "((a,b),(e,f," (ambiguity resolution) | |
3158 { | |
3159 p = ::boost::math::quaternion<T>(a,b); // too late to backtrack | |
3160 | |
3161 is >> g; // read "((a,b),(e,f,g" | |
3162 | |
3163 if (!is.good()) goto finish; | |
3164 | |
3165 is >> ch; // get the next lexeme | |
3166 | |
3167 if (!is.good()) goto finish; | |
3168 | |
3169 #ifdef BOOST_NO_STD_LOCALE | |
3170 cc = ch; | |
3171 #else | |
3172 cc = ct.narrow(ch, char()); | |
3173 #endif /* BOOST_NO_STD_LOCALE */ | |
3174 | |
3175 if (cc == ')') // read "((a,b),(e,f,g)" | |
3176 { | |
3177 is >> ch; // get the next lexeme | |
3178 | |
3179 if (!is.good()) goto finish; | |
3180 | |
3181 #ifdef BOOST_NO_STD_LOCALE | |
3182 cc = ch; | |
3183 #else | |
3184 cc = ct.narrow(ch, char()); | |
3185 #endif /* BOOST_NO_STD_LOCALE */ | |
3186 | |
3187 if (cc == ')') // read "((a,b),(e,f,g))" | |
3188 { | |
3189 q = ::boost::math::quaternion<T>(c,d,g); // "c" is actually "e" and "d" is actually "f" | |
3190 | |
3191 o = octonion<T>(p,q); | |
3192 } | |
3193 else // error | |
3194 { | |
3195 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3196 is.setstate(::std::ios::failbit); | |
3197 #else | |
3198 is.setstate(::std::ios_base::failbit); | |
3199 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3200 } | |
3201 } | |
3202 else if (cc == ',') // read "((a,b),(e,f,g," | |
3203 { | |
3204 is >> h; // read "((a,b),(e,f,g,h" | |
3205 | |
3206 if (!is.good()) goto finish; | |
3207 | |
3208 is >> ch; // get the next lexeme | |
3209 | |
3210 if (!is.good()) goto finish; | |
3211 | |
3212 #ifdef BOOST_NO_STD_LOCALE | |
3213 cc = ch; | |
3214 #else | |
3215 cc = ct.narrow(ch, char()); | |
3216 #endif /* BOOST_NO_STD_LOCALE */ | |
3217 | |
3218 if (cc == ')') // read "((a,b),(e,f,g,h)" | |
3219 { | |
3220 is >> ch; // get the next lexeme | |
3221 | |
3222 if (!is.good()) goto finish; | |
3223 | |
3224 #ifdef BOOST_NO_STD_LOCALE | |
3225 cc = ch; | |
3226 #else | |
3227 cc = ct.narrow(ch, char()); | |
3228 #endif /* BOOST_NO_STD_LOCALE */ | |
3229 | |
3230 if (cc == ')') // read ((a,b),(e,f,g,h))" | |
3231 { | |
3232 q = ::boost::math::quaternion<T>(c,d,g,h); // "c" is actually "e" and "d" is actually "f" | |
3233 | |
3234 o = octonion<T>(p,q); | |
3235 } | |
3236 else // error | |
3237 { | |
3238 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3239 is.setstate(::std::ios::failbit); | |
3240 #else | |
3241 is.setstate(::std::ios_base::failbit); | |
3242 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3243 } | |
3244 } | |
3245 else // error | |
3246 { | |
3247 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3248 is.setstate(::std::ios::failbit); | |
3249 #else | |
3250 is.setstate(::std::ios_base::failbit); | |
3251 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3252 } | |
3253 } | |
3254 else // error | |
3255 { | |
3256 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3257 is.setstate(::std::ios::failbit); | |
3258 #else | |
3259 is.setstate(::std::ios_base::failbit); | |
3260 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3261 } | |
3262 } | |
3263 else // error | |
3264 { | |
3265 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3266 is.setstate(::std::ios::failbit); | |
3267 #else | |
3268 is.setstate(::std::ios_base::failbit); | |
3269 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3270 } | |
3271 } | |
3272 } | |
3273 else // error | |
3274 { | |
3275 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3276 is.setstate(::std::ios::failbit); | |
3277 #else | |
3278 is.setstate(::std::ios_base::failbit); | |
3279 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3280 } | |
3281 } | |
3282 } | |
3283 else // error | |
3284 { | |
3285 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3286 is.setstate(::std::ios::failbit); | |
3287 #else | |
3288 is.setstate(::std::ios_base::failbit); | |
3289 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3290 } | |
3291 } | |
3292 else // error | |
3293 { | |
3294 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3295 is.setstate(::std::ios::failbit); | |
3296 #else | |
3297 is.setstate(::std::ios_base::failbit); | |
3298 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3299 } | |
3300 } | |
3301 else if (cc == ',') // read "((a,b," | |
3302 { | |
3303 is >> c; // read "((a,b,c" | |
3304 | |
3305 if (!is.good()) goto finish; | |
3306 | |
3307 is >> ch; // get the next lexeme | |
3308 | |
3309 if (!is.good()) goto finish; | |
3310 | |
3311 #ifdef BOOST_NO_STD_LOCALE | |
3312 cc = ch; | |
3313 #else | |
3314 cc = ct.narrow(ch, char()); | |
3315 #endif /* BOOST_NO_STD_LOCALE */ | |
3316 | |
3317 if (cc == ')') // read "((a,b,c)" | |
3318 { | |
3319 is >> ch; // get the next lexeme | |
3320 | |
3321 if (!is.good()) goto finish; | |
3322 | |
3323 #ifdef BOOST_NO_STD_LOCALE | |
3324 cc = ch; | |
3325 #else | |
3326 cc = ct.narrow(ch, char()); | |
3327 #endif /* BOOST_NO_STD_LOCALE */ | |
3328 | |
3329 if (cc == ')') // read "((a,b,c))" | |
3330 { | |
3331 o = octonion<T>(a,b,c); | |
3332 } | |
3333 else if (cc == ',') // read "((a,b,c)," | |
3334 { | |
3335 p = ::boost::math::quaternion<T>(a,b,c); | |
3336 | |
3337 is >> q; // read "((a,b,c),q" | |
3338 | |
3339 if (!is.good()) goto finish; | |
3340 | |
3341 is >> ch; // get the next lexeme | |
3342 | |
3343 if (!is.good()) goto finish; | |
3344 | |
3345 #ifdef BOOST_NO_STD_LOCALE | |
3346 cc = ch; | |
3347 #else | |
3348 cc = ct.narrow(ch, char()); | |
3349 #endif /* BOOST_NO_STD_LOCALE */ | |
3350 | |
3351 if (cc == ')') // read "((a,b,c),q)" | |
3352 { | |
3353 o = octonion<T>(p,q); | |
3354 } | |
3355 else // error | |
3356 { | |
3357 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3358 is.setstate(::std::ios::failbit); | |
3359 #else | |
3360 is.setstate(::std::ios_base::failbit); | |
3361 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3362 } | |
3363 } | |
3364 else // error | |
3365 { | |
3366 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3367 is.setstate(::std::ios::failbit); | |
3368 #else | |
3369 is.setstate(::std::ios_base::failbit); | |
3370 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3371 } | |
3372 } | |
3373 else if (cc == ',') // read "((a,b,c," | |
3374 { | |
3375 is >> d; // read "((a,b,c,d" | |
3376 | |
3377 if (!is.good()) goto finish; | |
3378 | |
3379 is >> ch; // get the next lexeme | |
3380 | |
3381 if (!is.good()) goto finish; | |
3382 | |
3383 #ifdef BOOST_NO_STD_LOCALE | |
3384 cc = ch; | |
3385 #else | |
3386 cc = ct.narrow(ch, char()); | |
3387 #endif /* BOOST_NO_STD_LOCALE */ | |
3388 | |
3389 if (cc == ')') // read "((a,b,c,d)" | |
3390 { | |
3391 is >> ch; // get the next lexeme | |
3392 | |
3393 if (!is.good()) goto finish; | |
3394 | |
3395 #ifdef BOOST_NO_STD_LOCALE | |
3396 cc = ch; | |
3397 #else | |
3398 cc = ct.narrow(ch, char()); | |
3399 #endif /* BOOST_NO_STD_LOCALE */ | |
3400 | |
3401 if (cc == ')') // read "((a,b,c,d))" | |
3402 { | |
3403 o = octonion<T>(a,b,c,d); | |
3404 } | |
3405 else if (cc == ',') // read "((a,b,c,d)," | |
3406 { | |
3407 p = ::boost::math::quaternion<T>(a,b,c,d); | |
3408 | |
3409 is >> q; // read "((a,b,c,d),q" | |
3410 | |
3411 if (!is.good()) goto finish; | |
3412 | |
3413 is >> ch; // get the next lexeme | |
3414 | |
3415 if (!is.good()) goto finish; | |
3416 | |
3417 #ifdef BOOST_NO_STD_LOCALE | |
3418 cc = ch; | |
3419 #else | |
3420 cc = ct.narrow(ch, char()); | |
3421 #endif /* BOOST_NO_STD_LOCALE */ | |
3422 | |
3423 if (cc == ')') // read "((a,b,c,d),q)" | |
3424 { | |
3425 o = octonion<T>(p,q); | |
3426 } | |
3427 else // error | |
3428 { | |
3429 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3430 is.setstate(::std::ios::failbit); | |
3431 #else | |
3432 is.setstate(::std::ios_base::failbit); | |
3433 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3434 } | |
3435 } | |
3436 else // error | |
3437 { | |
3438 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3439 is.setstate(::std::ios::failbit); | |
3440 #else | |
3441 is.setstate(::std::ios_base::failbit); | |
3442 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3443 } | |
3444 } | |
3445 else // error | |
3446 { | |
3447 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3448 is.setstate(::std::ios::failbit); | |
3449 #else | |
3450 is.setstate(::std::ios_base::failbit); | |
3451 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3452 } | |
3453 } | |
3454 else // error | |
3455 { | |
3456 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3457 is.setstate(::std::ios::failbit); | |
3458 #else | |
3459 is.setstate(::std::ios_base::failbit); | |
3460 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3461 } | |
3462 } | |
3463 else // error | |
3464 { | |
3465 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3466 is.setstate(::std::ios::failbit); | |
3467 #else | |
3468 is.setstate(::std::ios_base::failbit); | |
3469 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3470 } | |
3471 } | |
3472 } | |
3473 else // error | |
3474 { | |
3475 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3476 is.setstate(::std::ios::failbit); | |
3477 #else | |
3478 is.setstate(::std::ios_base::failbit); | |
3479 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3480 } | |
3481 } | |
3482 } | |
3483 else // read "(a" | |
3484 { | |
3485 is.putback(ch); | |
3486 | |
3487 is >> a; // we extract the first component | |
3488 | |
3489 if (!is.good()) goto finish; | |
3490 | |
3491 is >> ch; // get the next lexeme | |
3492 | |
3493 if (!is.good()) goto finish; | |
3494 | |
3495 #ifdef BOOST_NO_STD_LOCALE | |
3496 cc = ch; | |
3497 #else | |
3498 cc = ct.narrow(ch, char()); | |
3499 #endif /* BOOST_NO_STD_LOCALE */ | |
3500 | |
3501 if (cc == ')') // read "(a)" | |
3502 { | |
3503 o = octonion<T>(a); | |
3504 } | |
3505 else if (cc == ',') // read "(a," | |
3506 { | |
3507 is >> ch; // get the next lexeme | |
3508 | |
3509 if (!is.good()) goto finish; | |
3510 | |
3511 #ifdef BOOST_NO_STD_LOCALE | |
3512 cc = ch; | |
3513 #else | |
3514 cc = ct.narrow(ch, char()); | |
3515 #endif /* BOOST_NO_STD_LOCALE */ | |
3516 | |
3517 if (cc == '(') // read "(a,(" | |
3518 { | |
3519 is >> ch; // get the next lexeme | |
3520 | |
3521 if (!is.good()) goto finish; | |
3522 | |
3523 #ifdef BOOST_NO_STD_LOCALE | |
3524 cc = ch; | |
3525 #else | |
3526 cc = ct.narrow(ch, char()); | |
3527 #endif /* BOOST_NO_STD_LOCALE */ | |
3528 | |
3529 if (cc == '(') // read "(a,((" | |
3530 { | |
3531 p = ::boost::math::quaternion<T>(a); | |
3532 | |
3533 is.putback(ch); | |
3534 | |
3535 is.putback(ch); // we backtrack twice, with the same value | |
3536 | |
3537 is >> q; // read "(a,q" | |
3538 | |
3539 if (!is.good()) goto finish; | |
3540 | |
3541 is >> ch; // get the next lexeme | |
3542 | |
3543 if (!is.good()) goto finish; | |
3544 | |
3545 #ifdef BOOST_NO_STD_LOCALE | |
3546 cc = ch; | |
3547 #else | |
3548 cc = ct.narrow(ch, char()); | |
3549 #endif /* BOOST_NO_STD_LOCALE */ | |
3550 | |
3551 if (cc == ')') // read "(a,q)" | |
3552 { | |
3553 o = octonion<T>(p,q); | |
3554 } | |
3555 else // error | |
3556 { | |
3557 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3558 is.setstate(::std::ios::failbit); | |
3559 #else | |
3560 is.setstate(::std::ios_base::failbit); | |
3561 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3562 } | |
3563 } | |
3564 else // read "(a,(c" or "(a,(e" | |
3565 { | |
3566 is.putback(ch); | |
3567 | |
3568 is >> c; | |
3569 | |
3570 if (!is.good()) goto finish; | |
3571 | |
3572 is >> ch; // get the next lexeme | |
3573 | |
3574 if (!is.good()) goto finish; | |
3575 | |
3576 #ifdef BOOST_NO_STD_LOCALE | |
3577 cc = ch; | |
3578 #else | |
3579 cc = ct.narrow(ch, char()); | |
3580 #endif /* BOOST_NO_STD_LOCALE */ | |
3581 | |
3582 if (cc == ')') // read "(a,(c)" (ambiguity resolution) | |
3583 { | |
3584 is >> ch; // get the next lexeme | |
3585 | |
3586 if (!is.good()) goto finish; | |
3587 | |
3588 #ifdef BOOST_NO_STD_LOCALE | |
3589 cc = ch; | |
3590 #else | |
3591 cc = ct.narrow(ch, char()); | |
3592 #endif /* BOOST_NO_STD_LOCALE */ | |
3593 | |
3594 if (cc == ')') // read "(a,(c))" | |
3595 { | |
3596 o = octonion<T>(a,b,c); | |
3597 } | |
3598 else if (cc == ',') // read "(a,(c)," | |
3599 { | |
3600 u = ::std::complex<T>(a); | |
3601 | |
3602 v = ::std::complex<T>(c); | |
3603 | |
3604 is >> x; // read "(a,(c),x" | |
3605 | |
3606 if (!is.good()) goto finish; | |
3607 | |
3608 is >> ch; // get the next lexeme | |
3609 | |
3610 if (!is.good()) goto finish; | |
3611 | |
3612 #ifdef BOOST_NO_STD_LOCALE | |
3613 cc = ch; | |
3614 #else | |
3615 cc = ct.narrow(ch, char()); | |
3616 #endif /* BOOST_NO_STD_LOCALE */ | |
3617 | |
3618 if (cc == ')') // read "(a,(c),x)" | |
3619 { | |
3620 o = octonion<T>(u,v,x); | |
3621 } | |
3622 else if (cc == ',') // read "(a,(c),x," | |
3623 { | |
3624 is >> y; // read "(a,(c),x,y" | |
3625 | |
3626 if (!is.good()) goto finish; | |
3627 | |
3628 is >> ch; // get the next lexeme | |
3629 | |
3630 if (!is.good()) goto finish; | |
3631 | |
3632 #ifdef BOOST_NO_STD_LOCALE | |
3633 cc = ch; | |
3634 #else | |
3635 cc = ct.narrow(ch, char()); | |
3636 #endif /* BOOST_NO_STD_LOCALE */ | |
3637 | |
3638 if (cc == ')') // read "(a,(c),x,y)" | |
3639 { | |
3640 o = octonion<T>(u,v,x,y); | |
3641 } | |
3642 else // error | |
3643 { | |
3644 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3645 is.setstate(::std::ios::failbit); | |
3646 #else | |
3647 is.setstate(::std::ios_base::failbit); | |
3648 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3649 } | |
3650 } | |
3651 else // error | |
3652 { | |
3653 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3654 is.setstate(::std::ios::failbit); | |
3655 #else | |
3656 is.setstate(::std::ios_base::failbit); | |
3657 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3658 } | |
3659 } | |
3660 else // error | |
3661 { | |
3662 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3663 is.setstate(::std::ios::failbit); | |
3664 #else | |
3665 is.setstate(::std::ios_base::failbit); | |
3666 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3667 } | |
3668 } | |
3669 else if (cc == ',') // read "(a,(c," or "(a,(e," | |
3670 { | |
3671 is >> ch; // get the next lexeme | |
3672 | |
3673 if (!is.good()) goto finish; | |
3674 | |
3675 #ifdef BOOST_NO_STD_LOCALE | |
3676 cc = ch; | |
3677 #else | |
3678 cc = ct.narrow(ch, char()); | |
3679 #endif /* BOOST_NO_STD_LOCALE */ | |
3680 | |
3681 if (cc == '(') // read "(a,(e,(" (ambiguity resolution) | |
3682 { | |
3683 u = ::std::complex<T>(a); | |
3684 | |
3685 x = ::std::complex<T>(c); // "c" is actually "e" | |
3686 | |
3687 is.putback(ch); // we backtrack | |
3688 | |
3689 is >> y; // read "(a,(e,y" | |
3690 | |
3691 if (!is.good()) goto finish; | |
3692 | |
3693 is >> ch; // get the next lexeme | |
3694 | |
3695 if (!is.good()) goto finish; | |
3696 | |
3697 #ifdef BOOST_NO_STD_LOCALE | |
3698 cc = ch; | |
3699 #else | |
3700 cc = ct.narrow(ch, char()); | |
3701 #endif /* BOOST_NO_STD_LOCALE */ | |
3702 | |
3703 if (cc == ')') // read "(a,(e,y)" | |
3704 { | |
3705 is >> ch; // get the next lexeme | |
3706 | |
3707 if (!is.good()) goto finish; | |
3708 | |
3709 #ifdef BOOST_NO_STD_LOCALE | |
3710 cc = ch; | |
3711 #else | |
3712 cc = ct.narrow(ch, char()); | |
3713 #endif /* BOOST_NO_STD_LOCALE */ | |
3714 | |
3715 if (cc == ')') // read "(a,(e,y))" | |
3716 { | |
3717 o = octonion<T>(u,v,x,y); | |
3718 } | |
3719 else // error | |
3720 { | |
3721 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3722 is.setstate(::std::ios::failbit); | |
3723 #else | |
3724 is.setstate(::std::ios_base::failbit); | |
3725 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3726 } | |
3727 } | |
3728 else // error | |
3729 { | |
3730 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3731 is.setstate(::std::ios::failbit); | |
3732 #else | |
3733 is.setstate(::std::ios_base::failbit); | |
3734 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3735 } | |
3736 } | |
3737 else // read "(a,(c,d" or "(a,(e,f" | |
3738 { | |
3739 is.putback(ch); | |
3740 | |
3741 is >> d; | |
3742 | |
3743 if (!is.good()) goto finish; | |
3744 | |
3745 is >> ch; // get the next lexeme | |
3746 | |
3747 if (!is.good()) goto finish; | |
3748 | |
3749 #ifdef BOOST_NO_STD_LOCALE | |
3750 cc = ch; | |
3751 #else | |
3752 cc = ct.narrow(ch, char()); | |
3753 #endif /* BOOST_NO_STD_LOCALE */ | |
3754 | |
3755 if (cc == ')') // read "(a,(c,d)" (ambiguity resolution) | |
3756 { | |
3757 is >> ch; // get the next lexeme | |
3758 | |
3759 if (!is.good()) goto finish; | |
3760 | |
3761 #ifdef BOOST_NO_STD_LOCALE | |
3762 cc = ch; | |
3763 #else | |
3764 cc = ct.narrow(ch, char()); | |
3765 #endif /* BOOST_NO_STD_LOCALE */ | |
3766 | |
3767 if (cc == ')') // read "(a,(c,d))" | |
3768 { | |
3769 o = octonion<T>(a,b,c,d); | |
3770 } | |
3771 else if (cc == ',') // read "(a,(c,d)," | |
3772 { | |
3773 u = ::std::complex<T>(a); | |
3774 | |
3775 v = ::std::complex<T>(c,d); | |
3776 | |
3777 is >> x; // read "(a,(c,d),x" | |
3778 | |
3779 if (!is.good()) goto finish; | |
3780 | |
3781 is >> ch; // get the next lexeme | |
3782 | |
3783 if (!is.good()) goto finish; | |
3784 | |
3785 #ifdef BOOST_NO_STD_LOCALE | |
3786 cc = ch; | |
3787 #else | |
3788 cc = ct.narrow(ch, char()); | |
3789 #endif /* BOOST_NO_STD_LOCALE */ | |
3790 | |
3791 if (cc == ')') // read "(a,(c,d),x)" | |
3792 { | |
3793 o = octonion<T>(u,v,x); | |
3794 } | |
3795 else if (cc == ',') // read "(a,(c,d),x," | |
3796 { | |
3797 is >> y; // read "(a,(c,d),x,y" | |
3798 | |
3799 if (!is.good()) goto finish; | |
3800 | |
3801 is >> ch; // get the next lexeme | |
3802 | |
3803 if (!is.good()) goto finish; | |
3804 | |
3805 #ifdef BOOST_NO_STD_LOCALE | |
3806 cc = ch; | |
3807 #else | |
3808 cc = ct.narrow(ch, char()); | |
3809 #endif /* BOOST_NO_STD_LOCALE */ | |
3810 | |
3811 if (cc == ')') // read "(a,(c,d),x,y)" | |
3812 { | |
3813 o = octonion<T>(u,v,x,y); | |
3814 } | |
3815 else // error | |
3816 { | |
3817 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3818 is.setstate(::std::ios::failbit); | |
3819 #else | |
3820 is.setstate(::std::ios_base::failbit); | |
3821 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3822 } | |
3823 } | |
3824 else // error | |
3825 { | |
3826 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3827 is.setstate(::std::ios::failbit); | |
3828 #else | |
3829 is.setstate(::std::ios_base::failbit); | |
3830 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3831 } | |
3832 } | |
3833 else // error | |
3834 { | |
3835 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3836 is.setstate(::std::ios::failbit); | |
3837 #else | |
3838 is.setstate(::std::ios_base::failbit); | |
3839 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3840 } | |
3841 } | |
3842 else if (cc == ',') // read "(a,(e,f," (ambiguity resolution) | |
3843 { | |
3844 p = ::boost::math::quaternion<T>(a); | |
3845 | |
3846 is >> g; // read "(a,(e,f,g" | |
3847 | |
3848 if (!is.good()) goto finish; | |
3849 | |
3850 is >> ch; // get the next lexeme | |
3851 | |
3852 if (!is.good()) goto finish; | |
3853 | |
3854 #ifdef BOOST_NO_STD_LOCALE | |
3855 cc = ch; | |
3856 #else | |
3857 cc = ct.narrow(ch, char()); | |
3858 #endif /* BOOST_NO_STD_LOCALE */ | |
3859 | |
3860 if (cc == ')') // read "(a,(e,f,g)" | |
3861 { | |
3862 is >> ch; // get the next lexeme | |
3863 | |
3864 if (!is.good()) goto finish; | |
3865 | |
3866 #ifdef BOOST_NO_STD_LOCALE | |
3867 cc = ch; | |
3868 #else | |
3869 cc = ct.narrow(ch, char()); | |
3870 #endif /* BOOST_NO_STD_LOCALE */ | |
3871 | |
3872 if (cc == ')') // read "(a,(e,f,g))" | |
3873 { | |
3874 q = ::boost::math::quaternion<T>(c,d,g); // "c" is actually "e" and "d" is actually "f" | |
3875 | |
3876 o = octonion<T>(p,q); | |
3877 } | |
3878 else // error | |
3879 { | |
3880 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3881 is.setstate(::std::ios::failbit); | |
3882 #else | |
3883 is.setstate(::std::ios_base::failbit); | |
3884 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3885 } | |
3886 } | |
3887 else if (cc == ',') // read "(a,(e,f,g," | |
3888 { | |
3889 is >> h; // read "(a,(e,f,g,h" | |
3890 | |
3891 if (!is.good()) goto finish; | |
3892 | |
3893 is >> ch; // get the next lexeme | |
3894 | |
3895 if (!is.good()) goto finish; | |
3896 | |
3897 #ifdef BOOST_NO_STD_LOCALE | |
3898 cc = ch; | |
3899 #else | |
3900 cc = ct.narrow(ch, char()); | |
3901 #endif /* BOOST_NO_STD_LOCALE */ | |
3902 | |
3903 if (cc == ')') // read "(a,(e,f,g,h)" | |
3904 { | |
3905 is >> ch; // get the next lexeme | |
3906 | |
3907 if (!is.good()) goto finish; | |
3908 | |
3909 #ifdef BOOST_NO_STD_LOCALE | |
3910 cc = ch; | |
3911 #else | |
3912 cc = ct.narrow(ch, char()); | |
3913 #endif /* BOOST_NO_STD_LOCALE */ | |
3914 | |
3915 if (cc == ')') // read "(a,(e,f,g,h))" | |
3916 { | |
3917 q = ::boost::math::quaternion<T>(c,d,g,h); // "c" is actually "e" and "d" is actually "f" | |
3918 | |
3919 o = octonion<T>(p,q); | |
3920 } | |
3921 else // error | |
3922 { | |
3923 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3924 is.setstate(::std::ios::failbit); | |
3925 #else | |
3926 is.setstate(::std::ios_base::failbit); | |
3927 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3928 } | |
3929 } | |
3930 else // error | |
3931 { | |
3932 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3933 is.setstate(::std::ios::failbit); | |
3934 #else | |
3935 is.setstate(::std::ios_base::failbit); | |
3936 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3937 } | |
3938 } | |
3939 else // error | |
3940 { | |
3941 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3942 is.setstate(::std::ios::failbit); | |
3943 #else | |
3944 is.setstate(::std::ios_base::failbit); | |
3945 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3946 } | |
3947 } | |
3948 else // error | |
3949 { | |
3950 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3951 is.setstate(::std::ios::failbit); | |
3952 #else | |
3953 is.setstate(::std::ios_base::failbit); | |
3954 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3955 } | |
3956 } | |
3957 } | |
3958 else // error | |
3959 { | |
3960 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
3961 is.setstate(::std::ios::failbit); | |
3962 #else | |
3963 is.setstate(::std::ios_base::failbit); | |
3964 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
3965 } | |
3966 } | |
3967 } | |
3968 else // read "(a,b" or "(a,c" (ambiguity resolution) | |
3969 { | |
3970 is.putback(ch); | |
3971 | |
3972 is >> b; | |
3973 | |
3974 if (!is.good()) goto finish; | |
3975 | |
3976 is >> ch; // get the next lexeme | |
3977 | |
3978 if (!is.good()) goto finish; | |
3979 | |
3980 #ifdef BOOST_NO_STD_LOCALE | |
3981 cc = ch; | |
3982 #else | |
3983 cc = ct.narrow(ch, char()); | |
3984 #endif /* BOOST_NO_STD_LOCALE */ | |
3985 | |
3986 if (cc == ')') // read "(a,b)" (ambiguity resolution) | |
3987 { | |
3988 o = octonion<T>(a,b); | |
3989 } | |
3990 else if (cc == ',') // read "(a,b," or "(a,c," | |
3991 { | |
3992 is >> ch; // get the next lexeme | |
3993 | |
3994 if (!is.good()) goto finish; | |
3995 | |
3996 #ifdef BOOST_NO_STD_LOCALE | |
3997 cc = ch; | |
3998 #else | |
3999 cc = ct.narrow(ch, char()); | |
4000 #endif /* BOOST_NO_STD_LOCALE */ | |
4001 | |
4002 if (cc == '(') // read "(a,c,(" (ambiguity resolution) | |
4003 { | |
4004 u = ::std::complex<T>(a); | |
4005 | |
4006 v = ::std::complex<T>(b); // "b" is actually "c" | |
4007 | |
4008 is.putback(ch); // we backtrack | |
4009 | |
4010 is >> x; // read "(a,c,x" | |
4011 | |
4012 if (!is.good()) goto finish; | |
4013 | |
4014 is >> ch; // get the next lexeme | |
4015 | |
4016 if (!is.good()) goto finish; | |
4017 | |
4018 #ifdef BOOST_NO_STD_LOCALE | |
4019 cc = ch; | |
4020 #else | |
4021 cc = ct.narrow(ch, char()); | |
4022 #endif /* BOOST_NO_STD_LOCALE */ | |
4023 | |
4024 if (cc == ')') // read "(a,c,x)" | |
4025 { | |
4026 o = octonion<T>(u,v,x); | |
4027 } | |
4028 else if (cc == ',') // read "(a,c,x," | |
4029 { | |
4030 is >> y; // read "(a,c,x,y" // read "(a,c,x" | |
4031 | |
4032 if (!is.good()) goto finish; | |
4033 | |
4034 is >> ch; // get the next lexeme | |
4035 | |
4036 if (!is.good()) goto finish; | |
4037 | |
4038 #ifdef BOOST_NO_STD_LOCALE | |
4039 cc = ch; | |
4040 #else | |
4041 cc = ct.narrow(ch, char()); | |
4042 #endif /* BOOST_NO_STD_LOCALE */ | |
4043 | |
4044 if (cc == ')') // read "(a,c,x,y)" | |
4045 { | |
4046 o = octonion<T>(u,v,x,y); | |
4047 } | |
4048 else // error | |
4049 { | |
4050 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4051 is.setstate(::std::ios::failbit); | |
4052 #else | |
4053 is.setstate(::std::ios_base::failbit); | |
4054 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4055 } | |
4056 } | |
4057 else // error | |
4058 { | |
4059 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4060 is.setstate(::std::ios::failbit); | |
4061 #else | |
4062 is.setstate(::std::ios_base::failbit); | |
4063 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4064 } | |
4065 } | |
4066 else // read "(a,b,c" or "(a,c,e" | |
4067 { | |
4068 is.putback(ch); | |
4069 | |
4070 is >> c; | |
4071 | |
4072 if (!is.good()) goto finish; | |
4073 | |
4074 is >> ch; // get the next lexeme | |
4075 | |
4076 if (!is.good()) goto finish; | |
4077 | |
4078 #ifdef BOOST_NO_STD_LOCALE | |
4079 cc = ch; | |
4080 #else | |
4081 cc = ct.narrow(ch, char()); | |
4082 #endif /* BOOST_NO_STD_LOCALE */ | |
4083 | |
4084 if (cc == ')') // read "(a,b,c)" (ambiguity resolution) | |
4085 { | |
4086 o = octonion<T>(a,b,c); | |
4087 } | |
4088 else if (cc == ',') // read "(a,b,c," or "(a,c,e," | |
4089 { | |
4090 is >> ch; // get the next lexeme | |
4091 | |
4092 if (!is.good()) goto finish; | |
4093 | |
4094 #ifdef BOOST_NO_STD_LOCALE | |
4095 cc = ch; | |
4096 #else | |
4097 cc = ct.narrow(ch, char()); | |
4098 #endif /* BOOST_NO_STD_LOCALE */ | |
4099 | |
4100 if (cc == '(') // read "(a,c,e,(") (ambiguity resolution) | |
4101 { | |
4102 u = ::std::complex<T>(a); | |
4103 | |
4104 v = ::std::complex<T>(b); // "b" is actually "c" | |
4105 | |
4106 x = ::std::complex<T>(c); // "c" is actually "e" | |
4107 | |
4108 is.putback(ch); // we backtrack | |
4109 | |
4110 is >> y; // read "(a,c,e,y" | |
4111 | |
4112 if (!is.good()) goto finish; | |
4113 | |
4114 is >> ch; // get the next lexeme | |
4115 | |
4116 if (!is.good()) goto finish; | |
4117 | |
4118 #ifdef BOOST_NO_STD_LOCALE | |
4119 cc = ch; | |
4120 #else | |
4121 cc = ct.narrow(ch, char()); | |
4122 #endif /* BOOST_NO_STD_LOCALE */ | |
4123 | |
4124 if (cc == ')') // read "(a,c,e,y)" | |
4125 { | |
4126 o = octonion<T>(u,v,x,y); | |
4127 } | |
4128 else // error | |
4129 { | |
4130 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4131 is.setstate(::std::ios::failbit); | |
4132 #else | |
4133 is.setstate(::std::ios_base::failbit); | |
4134 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4135 } | |
4136 } | |
4137 else // read "(a,b,c,d" (ambiguity resolution) | |
4138 { | |
4139 is.putback(ch); // we backtrack | |
4140 | |
4141 is >> d; | |
4142 | |
4143 if (!is.good()) goto finish; | |
4144 | |
4145 is >> ch; // get the next lexeme | |
4146 | |
4147 if (!is.good()) goto finish; | |
4148 | |
4149 #ifdef BOOST_NO_STD_LOCALE | |
4150 cc = ch; | |
4151 #else | |
4152 cc = ct.narrow(ch, char()); | |
4153 #endif /* BOOST_NO_STD_LOCALE */ | |
4154 | |
4155 if (cc == ')') // read "(a,b,c,d)" | |
4156 { | |
4157 o = octonion<T>(a,b,c,d); | |
4158 } | |
4159 else if (cc == ',') // read "(a,b,c,d," | |
4160 { | |
4161 is >> e; // read "(a,b,c,d,e" | |
4162 | |
4163 if (!is.good()) goto finish; | |
4164 | |
4165 is >> ch; // get the next lexeme | |
4166 | |
4167 if (!is.good()) goto finish; | |
4168 | |
4169 #ifdef BOOST_NO_STD_LOCALE | |
4170 cc = ch; | |
4171 #else | |
4172 cc = ct.narrow(ch, char()); | |
4173 #endif /* BOOST_NO_STD_LOCALE */ | |
4174 | |
4175 if (cc == ')') // read "(a,b,c,d,e)" | |
4176 { | |
4177 o = octonion<T>(a,b,c,d,e); | |
4178 } | |
4179 else if (cc == ',') // read "(a,b,c,d,e," | |
4180 { | |
4181 is >> f; // read "(a,b,c,d,e,f" | |
4182 | |
4183 if (!is.good()) goto finish; | |
4184 | |
4185 is >> ch; // get the next lexeme | |
4186 | |
4187 if (!is.good()) goto finish; | |
4188 | |
4189 #ifdef BOOST_NO_STD_LOCALE | |
4190 cc = ch; | |
4191 #else | |
4192 cc = ct.narrow(ch, char()); | |
4193 #endif /* BOOST_NO_STD_LOCALE */ | |
4194 | |
4195 if (cc == ')') // read "(a,b,c,d,e,f)" | |
4196 { | |
4197 o = octonion<T>(a,b,c,d,e,f); | |
4198 } | |
4199 else if (cc == ',') // read "(a,b,c,d,e,f," | |
4200 { | |
4201 is >> g; // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f" | |
4202 | |
4203 if (!is.good()) goto finish; | |
4204 | |
4205 is >> ch; // get the next lexeme | |
4206 | |
4207 if (!is.good()) goto finish; | |
4208 | |
4209 #ifdef BOOST_NO_STD_LOCALE | |
4210 cc = ch; | |
4211 #else | |
4212 cc = ct.narrow(ch, char()); | |
4213 #endif /* BOOST_NO_STD_LOCALE */ | |
4214 | |
4215 if (cc == ')') // read "(a,b,c,d,e,f,g)" | |
4216 { | |
4217 o = octonion<T>(a,b,c,d,e,f,g); | |
4218 } | |
4219 else if (cc == ',') // read "(a,b,c,d,e,f,g," | |
4220 { | |
4221 is >> h; // read "(a,b,c,d,e,f,g,h" // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f" | |
4222 | |
4223 if (!is.good()) goto finish; | |
4224 | |
4225 is >> ch; // get the next lexeme | |
4226 | |
4227 if (!is.good()) goto finish; | |
4228 | |
4229 #ifdef BOOST_NO_STD_LOCALE | |
4230 cc = ch; | |
4231 #else | |
4232 cc = ct.narrow(ch, char()); | |
4233 #endif /* BOOST_NO_STD_LOCALE */ | |
4234 | |
4235 if (cc == ')') // read "(a,b,c,d,e,f,g,h)" | |
4236 { | |
4237 o = octonion<T>(a,b,c,d,e,f,g,h); | |
4238 } | |
4239 else // error | |
4240 { | |
4241 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4242 is.setstate(::std::ios::failbit); | |
4243 #else | |
4244 is.setstate(::std::ios_base::failbit); | |
4245 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4246 } | |
4247 } | |
4248 else // error | |
4249 { | |
4250 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4251 is.setstate(::std::ios::failbit); | |
4252 #else | |
4253 is.setstate(::std::ios_base::failbit); | |
4254 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4255 } | |
4256 } | |
4257 else // error | |
4258 { | |
4259 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4260 is.setstate(::std::ios::failbit); | |
4261 #else | |
4262 is.setstate(::std::ios_base::failbit); | |
4263 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4264 } | |
4265 } | |
4266 else // error | |
4267 { | |
4268 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4269 is.setstate(::std::ios::failbit); | |
4270 #else | |
4271 is.setstate(::std::ios_base::failbit); | |
4272 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4273 } | |
4274 } | |
4275 else // error | |
4276 { | |
4277 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4278 is.setstate(::std::ios::failbit); | |
4279 #else | |
4280 is.setstate(::std::ios_base::failbit); | |
4281 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4282 } | |
4283 } | |
4284 } | |
4285 else // error | |
4286 { | |
4287 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4288 is.setstate(::std::ios::failbit); | |
4289 #else | |
4290 is.setstate(::std::ios_base::failbit); | |
4291 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4292 } | |
4293 } | |
4294 } | |
4295 else // error | |
4296 { | |
4297 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4298 is.setstate(::std::ios::failbit); | |
4299 #else | |
4300 is.setstate(::std::ios_base::failbit); | |
4301 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4302 } | |
4303 } | |
4304 } | |
4305 else // error | |
4306 { | |
4307 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4308 is.setstate(::std::ios::failbit); | |
4309 #else | |
4310 is.setstate(::std::ios_base::failbit); | |
4311 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4312 } | |
4313 } | |
4314 } | |
4315 else // format: a | |
4316 { | |
4317 is.putback(ch); | |
4318 | |
4319 is >> a; // we extract the first component | |
4320 | |
4321 if (!is.good()) goto finish; | |
4322 | |
4323 o = octonion<T>(a); | |
4324 } | |
4325 | |
4326 finish: | |
4327 return(is); | |
4328 } | |
4329 | |
4330 | |
4331 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4332 template<typename T> | |
4333 ::std::ostream & operator << ( ::std::ostream & os, | |
4334 octonion<T> const & o) | |
4335 #else | |
4336 template<typename T, typename charT, class traits> | |
4337 ::std::basic_ostream<charT,traits> & operator << ( ::std::basic_ostream<charT,traits> & os, | |
4338 octonion<T> const & o) | |
4339 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4340 { | |
4341 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4342 ::std::ostringstream s; | |
4343 #else | |
4344 ::std::basic_ostringstream<charT,traits> s; | |
4345 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4346 | |
4347 s.flags(os.flags()); | |
4348 #ifdef BOOST_NO_STD_LOCALE | |
4349 #else | |
4350 s.imbue(os.getloc()); | |
4351 #endif /* BOOST_NO_STD_LOCALE */ | |
4352 s.precision(os.precision()); | |
4353 | |
4354 s << '(' << o.R_component_1() << ',' | |
4355 << o.R_component_2() << ',' | |
4356 << o.R_component_3() << ',' | |
4357 << o.R_component_4() << ',' | |
4358 << o.R_component_5() << ',' | |
4359 << o.R_component_6() << ',' | |
4360 << o.R_component_7() << ',' | |
4361 << o.R_component_8() << ')'; | |
4362 | |
4363 return os << s.str(); | |
4364 } | |
4365 | |
4366 | |
4367 // values | |
4368 | |
4369 template<typename T> | |
4370 inline T real(octonion<T> const & o) | |
4371 { | |
4372 return(o.real()); | |
4373 } | |
4374 | |
4375 | |
4376 template<typename T> | |
4377 inline octonion<T> unreal(octonion<T> const & o) | |
4378 { | |
4379 return(o.unreal()); | |
4380 } | |
4381 | |
4382 | |
4383 #define BOOST_OCTONION_VALARRAY_LOADER \ | |
4384 using ::std::valarray; \ | |
4385 \ | |
4386 valarray<T> temp(8); \ | |
4387 \ | |
4388 temp[0] = o.R_component_1(); \ | |
4389 temp[1] = o.R_component_2(); \ | |
4390 temp[2] = o.R_component_3(); \ | |
4391 temp[3] = o.R_component_4(); \ | |
4392 temp[4] = o.R_component_5(); \ | |
4393 temp[5] = o.R_component_6(); \ | |
4394 temp[6] = o.R_component_7(); \ | |
4395 temp[7] = o.R_component_8(); | |
4396 | |
4397 | |
4398 template<typename T> | |
4399 inline T sup(octonion<T> const & o) | |
4400 { | |
4401 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | |
4402 using ::std::abs; | |
4403 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | |
4404 | |
4405 BOOST_OCTONION_VALARRAY_LOADER | |
4406 | |
4407 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4408 return((BOOST_GET_VALARRAY(T, abs(temp)).max)()); | |
4409 #else | |
4410 return((abs(temp).max)()); | |
4411 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4412 } | |
4413 | |
4414 | |
4415 template<typename T> | |
4416 inline T l1(octonion<T> const & o) | |
4417 { | |
4418 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | |
4419 using ::std::abs; | |
4420 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | |
4421 | |
4422 BOOST_OCTONION_VALARRAY_LOADER | |
4423 | |
4424 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4425 return(BOOST_GET_VALARRAY(T, abs(temp)).sum()); | |
4426 #else | |
4427 return(abs(temp).sum()); | |
4428 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4429 } | |
4430 | |
4431 | |
4432 template<typename T> | |
4433 inline T abs(const octonion<T> & o) | |
4434 { | |
4435 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP | |
4436 using ::std::abs; | |
4437 #endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ | |
4438 | |
4439 using ::std::sqrt; | |
4440 | |
4441 BOOST_OCTONION_VALARRAY_LOADER | |
4442 | |
4443 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4444 T maxim = (BOOST_GET_VALARRAY(T,abs(temp)).max)(); // overflow protection | |
4445 #else | |
4446 T maxim = (abs(temp).max)(); // overflow protection | |
4447 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4448 | |
4449 if (maxim == static_cast<T>(0)) | |
4450 { | |
4451 return(maxim); | |
4452 } | |
4453 else | |
4454 { | |
4455 T mixam = static_cast<T>(1)/maxim; // prefer multiplications over divisions | |
4456 | |
4457 temp *= mixam; | |
4458 | |
4459 temp *= temp; | |
4460 | |
4461 return(maxim*sqrt(temp.sum())); | |
4462 } | |
4463 | |
4464 //return(::std::sqrt(norm(o))); | |
4465 } | |
4466 | |
4467 | |
4468 #undef BOOST_OCTONION_VALARRAY_LOADER | |
4469 | |
4470 | |
4471 // Note: This is the Cayley norm, not the Euclidian norm... | |
4472 | |
4473 template<typename T> | |
4474 inline T norm(octonion<T> const & o) | |
4475 { | |
4476 return(real(o*conj(o))); | |
4477 } | |
4478 | |
4479 | |
4480 template<typename T> | |
4481 inline octonion<T> conj(octonion<T> const & o) | |
4482 { | |
4483 return(octonion<T>( +o.R_component_1(), | |
4484 -o.R_component_2(), | |
4485 -o.R_component_3(), | |
4486 -o.R_component_4(), | |
4487 -o.R_component_5(), | |
4488 -o.R_component_6(), | |
4489 -o.R_component_7(), | |
4490 -o.R_component_8())); | |
4491 } | |
4492 | |
4493 | |
4494 // Note: There is little point, for the octonions, to introduce the equivalents | |
4495 // to the complex "arg" and the quaternionic "cylindropolar". | |
4496 | |
4497 | |
4498 template<typename T> | |
4499 inline octonion<T> spherical(T const & rho, | |
4500 T const & theta, | |
4501 T const & phi1, | |
4502 T const & phi2, | |
4503 T const & phi3, | |
4504 T const & phi4, | |
4505 T const & phi5, | |
4506 T const & phi6) | |
4507 { | |
4508 using ::std::cos; | |
4509 using ::std::sin; | |
4510 | |
4511 //T a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); | |
4512 //T b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); | |
4513 //T c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); | |
4514 //T d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); | |
4515 //T e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6); | |
4516 //T f = sin(phi4)*cos(phi5)*cos(phi6); | |
4517 //T g = sin(phi5)*cos(phi6); | |
4518 //T h = sin(phi6); | |
4519 | |
4520 T courrant = static_cast<T>(1); | |
4521 | |
4522 T h = sin(phi6); | |
4523 | |
4524 courrant *= cos(phi6); | |
4525 | |
4526 T g = sin(phi5)*courrant; | |
4527 | |
4528 courrant *= cos(phi5); | |
4529 | |
4530 T f = sin(phi4)*courrant; | |
4531 | |
4532 courrant *= cos(phi4); | |
4533 | |
4534 T e = sin(phi3)*courrant; | |
4535 | |
4536 courrant *= cos(phi3); | |
4537 | |
4538 T d = sin(phi2)*courrant; | |
4539 | |
4540 courrant *= cos(phi2); | |
4541 | |
4542 T c = sin(phi1)*courrant; | |
4543 | |
4544 courrant *= cos(phi1); | |
4545 | |
4546 T b = sin(theta)*courrant; | |
4547 T a = cos(theta)*courrant; | |
4548 | |
4549 return(rho*octonion<T>(a,b,c,d,e,f,g,h)); | |
4550 } | |
4551 | |
4552 | |
4553 template<typename T> | |
4554 inline octonion<T> multipolar(T const & rho1, | |
4555 T const & theta1, | |
4556 T const & rho2, | |
4557 T const & theta2, | |
4558 T const & rho3, | |
4559 T const & theta3, | |
4560 T const & rho4, | |
4561 T const & theta4) | |
4562 { | |
4563 using ::std::cos; | |
4564 using ::std::sin; | |
4565 | |
4566 T a = rho1*cos(theta1); | |
4567 T b = rho1*sin(theta1); | |
4568 T c = rho2*cos(theta2); | |
4569 T d = rho2*sin(theta2); | |
4570 T e = rho3*cos(theta3); | |
4571 T f = rho3*sin(theta3); | |
4572 T g = rho4*cos(theta4); | |
4573 T h = rho4*sin(theta4); | |
4574 | |
4575 return(octonion<T>(a,b,c,d,e,f,g,h)); | |
4576 } | |
4577 | |
4578 | |
4579 template<typename T> | |
4580 inline octonion<T> cylindrical(T const & r, | |
4581 T const & angle, | |
4582 T const & h1, | |
4583 T const & h2, | |
4584 T const & h3, | |
4585 T const & h4, | |
4586 T const & h5, | |
4587 T const & h6) | |
4588 { | |
4589 using ::std::cos; | |
4590 using ::std::sin; | |
4591 | |
4592 T a = r*cos(angle); | |
4593 T b = r*sin(angle); | |
4594 | |
4595 return(octonion<T>(a,b,h1,h2,h3,h4,h5,h6)); | |
4596 } | |
4597 | |
4598 | |
4599 template<typename T> | |
4600 inline octonion<T> exp(octonion<T> const & o) | |
4601 { | |
4602 using ::std::exp; | |
4603 using ::std::cos; | |
4604 | |
4605 using ::boost::math::sinc_pi; | |
4606 | |
4607 T u = exp(real(o)); | |
4608 | |
4609 T z = abs(unreal(o)); | |
4610 | |
4611 T w = sinc_pi(z); | |
4612 | |
4613 return(u*octonion<T>(cos(z), | |
4614 w*o.R_component_2(), w*o.R_component_3(), | |
4615 w*o.R_component_4(), w*o.R_component_5(), | |
4616 w*o.R_component_6(), w*o.R_component_7(), | |
4617 w*o.R_component_8())); | |
4618 } | |
4619 | |
4620 | |
4621 template<typename T> | |
4622 inline octonion<T> cos(octonion<T> const & o) | |
4623 { | |
4624 using ::std::sin; | |
4625 using ::std::cos; | |
4626 using ::std::cosh; | |
4627 | |
4628 using ::boost::math::sinhc_pi; | |
4629 | |
4630 T z = abs(unreal(o)); | |
4631 | |
4632 T w = -sin(o.real())*sinhc_pi(z); | |
4633 | |
4634 return(octonion<T>(cos(o.real())*cosh(z), | |
4635 w*o.R_component_2(), w*o.R_component_3(), | |
4636 w*o.R_component_4(), w*o.R_component_5(), | |
4637 w*o.R_component_6(), w*o.R_component_7(), | |
4638 w*o.R_component_8())); | |
4639 } | |
4640 | |
4641 | |
4642 template<typename T> | |
4643 inline octonion<T> sin(octonion<T> const & o) | |
4644 { | |
4645 using ::std::sin; | |
4646 using ::std::cos; | |
4647 using ::std::cosh; | |
4648 | |
4649 using ::boost::math::sinhc_pi; | |
4650 | |
4651 T z = abs(unreal(o)); | |
4652 | |
4653 T w = +cos(o.real())*sinhc_pi(z); | |
4654 | |
4655 return(octonion<T>(sin(o.real())*cosh(z), | |
4656 w*o.R_component_2(), w*o.R_component_3(), | |
4657 w*o.R_component_4(), w*o.R_component_5(), | |
4658 w*o.R_component_6(), w*o.R_component_7(), | |
4659 w*o.R_component_8())); | |
4660 } | |
4661 | |
4662 | |
4663 template<typename T> | |
4664 inline octonion<T> tan(octonion<T> const & o) | |
4665 { | |
4666 return(sin(o)/cos(o)); | |
4667 } | |
4668 | |
4669 | |
4670 template<typename T> | |
4671 inline octonion<T> cosh(octonion<T> const & o) | |
4672 { | |
4673 return((exp(+o)+exp(-o))/static_cast<T>(2)); | |
4674 } | |
4675 | |
4676 | |
4677 template<typename T> | |
4678 inline octonion<T> sinh(octonion<T> const & o) | |
4679 { | |
4680 return((exp(+o)-exp(-o))/static_cast<T>(2)); | |
4681 } | |
4682 | |
4683 | |
4684 template<typename T> | |
4685 inline octonion<T> tanh(octonion<T> const & o) | |
4686 { | |
4687 return(sinh(o)/cosh(o)); | |
4688 } | |
4689 | |
4690 | |
4691 template<typename T> | |
4692 octonion<T> pow(octonion<T> const & o, | |
4693 int n) | |
4694 { | |
4695 if (n > 1) | |
4696 { | |
4697 int m = n>>1; | |
4698 | |
4699 octonion<T> result = pow(o, m); | |
4700 | |
4701 result *= result; | |
4702 | |
4703 if (n != (m<<1)) | |
4704 { | |
4705 result *= o; // n odd | |
4706 } | |
4707 | |
4708 return(result); | |
4709 } | |
4710 else if (n == 1) | |
4711 { | |
4712 return(o); | |
4713 } | |
4714 else if (n == 0) | |
4715 { | |
4716 return(octonion<T>(static_cast<T>(1))); | |
4717 } | |
4718 else /* n < 0 */ | |
4719 { | |
4720 return(pow(octonion<T>(static_cast<T>(1))/o,-n)); | |
4721 } | |
4722 } | |
4723 | |
4724 | |
4725 // helper templates for converting copy constructors (definition) | |
4726 | |
4727 namespace detail | |
4728 { | |
4729 | |
4730 template< typename T, | |
4731 typename U | |
4732 > | |
4733 octonion<T> octonion_type_converter(octonion<U> const & rhs) | |
4734 { | |
4735 return(octonion<T>( static_cast<T>(rhs.R_component_1()), | |
4736 static_cast<T>(rhs.R_component_2()), | |
4737 static_cast<T>(rhs.R_component_3()), | |
4738 static_cast<T>(rhs.R_component_4()), | |
4739 static_cast<T>(rhs.R_component_5()), | |
4740 static_cast<T>(rhs.R_component_6()), | |
4741 static_cast<T>(rhs.R_component_7()), | |
4742 static_cast<T>(rhs.R_component_8()))); | |
4743 } | |
4744 } | |
4745 } | |
4746 } | |
4747 | |
4748 | |
4749 #if BOOST_WORKAROUND(__GNUC__, < 3) | |
4750 #undef BOOST_GET_VALARRAY | |
4751 #endif /* BOOST_WORKAROUND(__GNUC__, < 3) */ | |
4752 | |
4753 | |
4754 #endif /* BOOST_OCTONION_HPP */ |