2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-19 04:22:09 +00:00

Special functions, octonions, quaternions by Hubert Holin

[SVN r10405]
This commit is contained in:
Jens Maurer
2001-06-23 08:12:29 +00:00
parent f483d1189b
commit 6453495428
80 changed files with 6987 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

70
octonion/index.htm Normal file
View File

@@ -0,0 +1,70 @@
<html>
<head>
<title>Boost class octonion</title>
<meta http-equiv="generator" content="Adobe GoLive 5">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2">
<tr>
<td bgcolor="#FFFFFF"><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" WIDTH="277" HEIGHT="86"></td>
<td><a href="../../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td>
<td><a href="../../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td>
<td><a href="../../../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td>
<td><a href="../../../more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td>
<td><a href="../../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td>
</tr>
</table>
<h2>The octonion Class</h2>
<p>Class quaternion provides an implementation of the mathematical object of the same name.&nbsp; See the documentation for details. <ul>
<li><a href="octonion.html">Documentation</a></li>
<li>Header <a href="../../../boost/math/octonion.hpp">octonion.hpp</a></li>
<li>Test program <a href="octonion_test.cpp">octonion_test.cpp</a></li>
<li>Download <a href="../../../more/download.html">all of Boost</a>.</li>
<li>Submitted by Hubert Holin.</li>
</ul>
<h3>Comments</h3>
<p>Compiles and runs under MetroWerk's CodeWarrior Pro 6.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %b %Y" startspan -->07 June 2001<!--webbot bot="Timestamp" endspan i-checksum="15233" -->
</p>
</body>
</html>

713
octonion/octonion.html Normal file
View File

@@ -0,0 +1,713 @@
<html>
<head>
<title>Class octonion Documentation</title>
<meta http-equiv="generator" content="Adobe GoLive 5">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Class octonion</h1>
<ul>
<li><a href="#Acknowledgements">Acknowledgements</a>
<li><a href="#Header File">Header File</a>
<li><a href="#Test Program">Test Program</a>
<li><a href="#Synopsis">Synopsis</a>
<li><a href="#Template class octonion">Template class <code>octonion</code></a>
<li><a href="#octonion specializations"><code>octonion</code> specializations</a>
<li><a href="#octonion member functions"><code>octonion</code> member functions</a>
<li><a href="#octonion member operators"><code>octonion</code> member operators</a>
<li><a href="#octonion non-member operations"><code>octonion</code> non-member operations</a>
<li><a href="#octonion value operations"><code>octonion</code> value operations</a>
<li><a href="#octonion transcendentals"><code>octonion</code> transcendentals</a>
<li><a href="#History">History</a>
</ul>
<p></p>
<p>Octonions, like <a href="../quaternion/quaternion.html">quaternions</a>, are a relative of complex numbers.</p>
<p>Octonions see some use in theoretical physics.</p>
<p>In practical terms, an octonion is simply an octuple of real numbers <img src="graphics/octonion_blurb.html1.jpeg" width="93" height="17" naturalsizeflag="3" align=absmiddle><font color="#000000">, which we can write in the form <img src="graphics/octonion_blurb.html2.jpeg" width="215" height="15" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, where <img src="graphics/octonion_blurb.html3.jpeg" width="6" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, <img src="graphics/octonion_blurb.html4.jpeg" width="8" height="13" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> and <img src="graphics/octonion_blurb.html5.jpeg" width="9" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> are the same objects as for quaternions, and <img src="graphics/octonion_blurb.html6.jpeg" width="11" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, <img src="graphics/octonion_blurb.html7.jpeg" width="10" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> , <img src="graphics/octonion_blurb.html8.jpeg" width="12" height="14" naturalsizeflag="3" align=absmiddle> and <img src="graphics/octonion_blurb.html9.jpeg" width="12" height="12" naturalsizeflag="3" align=absmiddle> are distinct objects which play essentially the same kind of role as <img src="graphics/octonion_blurb.html10.jpeg" width="6" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> (or <img src="graphics/octonion_blurb.html11.jpeg" width="8" height="13" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> or <img src="graphics/octonion_blurb.html12.jpeg" width="9" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000">).</font></p>
<p><font color="#000000">An addition and a multiplication is defined on the set of octonions, which generalize their quaternionic counterparts. The main novelty this time is that <strong>the multiplication is not only not commutative, is now not even associative</strong> (<cite>i.e.</cite> there are quaternions <img src="graphics/octonion_blurb.html13.jpeg" width="9" height="9" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, <img src="graphics/octonion_blurb.html14.jpeg" width="9" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> and <img src="graphics/octonion_blurb.html15.jpeg" width="8" height="8" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> such that <img src="graphics/octonion_blurb.html16.jpeg" width="72" height="16" naturalsizeflag="3" align=absmiddle></font><font color="#000000">). A way of remembering things is by using the following multiplication table:</font></p>
<div align="center">
<p><img src="graphics/octonion_blurb.html17.jpeg" width="243" height="158" naturalsizeflag="3" align=BOTTOM></p>
</div>
<p><font color="#000000">Octonions (and their kin) are described in far more details in this other <a href="../quaternion/TQE.pdf">document</a> (with <a href="../quaternion/TQE_EA.pdf">errata and addenda</a>).</font></p>
<p><font color="#000000">Some traditional constructs, such as the exponential, carry over without too much change into the realms of octonions, but other, such as taking a square root, do not (the fact that the exponential has a closed form is a result of the author, but the fact that the exponential exists at all for octonions is known since quite a long time ago).</font></p>
<h2><a name="Acknowledgements"></a>Acknowledgements</h2>
<p>The mathematical text has been typeset with <a href="http://www.nisus-soft.com/">Nisus Writer</a>. Jens Maurer has helped with portability and standard adherence, and was the Review Manager for this library. More acknowledgements in the History section. Thank you to all who contributed to the discution about this library.</p>
<h2><a name="Header File"></a>Header File</h2>
<p>The interface and implementation are both supplied by the header file <a href="../../boost/octonion.hpp">octonion.h</a>.</p>
<h2><a name="Test Program"></a>Test Program</h2>
<p>The <a href="octonion_test.cpp">octonion_test.cpp</a> test program tests octonions specialisations for float, double and long double (<a href="output.txt">sample output</a>).</p>
<p>It has been compiled and runs without error with the following C++ compilers:</p>
<blockquote>
<ul>
<li>MetroWerk's CodeWarrior Pro 6 on a Mac on a PowerPC G3
</ul>
</blockquote>
<h2><a name="Synopsis"></a>Synopsis</h2>
<pre><code>namespace boost
{
template&lt;typename T&gt; class <a href="#octonion">octonion</a>;
template&lt;&gt; class <a href="##octonion<float>">octonion&lt;float&gt;</a>;
template&lt;&gt; class <a href="##octonion<double>">octonion&lt;double&gt;</a>;
template&lt;&gt; class <a href="##octonion<long double>">octonion&lt;long double&gt;</a>;
// operators
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator *</a> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator /</a> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator +</a> (octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion non-member operations">operator -</a> (octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator ==</a> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#octonion non-member operations">operator !=</a> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T, typename charT, class traits&gt;
::std::basic_istream&lt;charT,traits&gt; &amp; <a href="#octonion non-member operations">operator &gt;&gt;</a> (::std::basic_istream&lt;charT,traits&gt; &amp; is, octonion&lt;T&gt; &amp; o);
template&lt;typename T, typename charT, class traits&gt;
::std::basic_ostream&lt;charT,traits&gt; &amp; <a href="#octonion non-member operations">operator &lt;&lt;</a> (::std::basic_ostream&lt;charT,traits&gt; &amp; os, octonion&lt;T&gt; const &amp; o);
// values
template&lt;typename T&gt; inline T <a href="#octonion value operations">real</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion value operations">unreal</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline T <a href="#octonion value operations">sup</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline T <a href="#octonion value operations">l1</a>(octonion&lt;T&gt;const &amp; o);
template&lt;typename T&gt; inline T <a href="#octonion value operations">abs</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline T <a href="#octonion value operations">norm</a>(octonion&lt;T&gt;const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion value operations">conj</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion value operations">spherical</a>(T const &amp; rho, T const &amp; theta, T const &amp; phi1, T const &amp; phi2, T const &amp; phi3, T const &amp; phi4, T const &amp; phi5, T const &amp; phi6);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion value operations">multipolar</a>(T const &amp; rho1, T const &amp; theta1, T const &amp; rho2, T const &amp; theta2, T const &amp; rho3, T const &amp; theta3, T const &amp; rho4, T const &amp; theta4);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#octonion value operations">cylindrical</a>(T const &amp; r, T const &amp; angle, T const &amp; h1, T const &amp; h2, T const &amp; h3, T const &amp; h4, T const &amp; h5, T const &amp; h6);
// transcendentals
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#exp">exp</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#cos">cos</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#sin">sin</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#tan">tan</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#cosh">cosh</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#sinh">sinh</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <a href="#tanh">tanh</a>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; octonion&lt;T&gt; <a href="#pow">pow</a>(octonion&lt;T&gt; const &amp; o, int n);
}</code></pre>
<h2><a name="Template class octonion"></a>Template class <code>octonion</code></h2>
<pre><code>namespace boost
{
<a name="octonion"></a> template&lt;typename T&gt;
class octonion
{
public:
typedef T <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">octonion</a>(T const &amp; requested_a = T(), T const &amp; requested_b = T(), T const &amp; requested_c = T(), T const &amp; requested_d = T(), T const & requested_e = T(), T const & requested_f = T(), T const & requested_g = T(), T const & requested_h = T());
explicit <a href="#Constructors">octonion</a>(::std::complex&lt;T&gt; const &amp; z0, ::std::complex&lt;T&gt; const &amp; z1 = ::std::complex&lt;T&gt;(), ::std::complex&lt;T&gt; const & z2 = ::std::complex&lt;T&gt;(), ::std::complex&lt;T&gt; const & z3 = ::std::complex&lt;T&gt;());
explicit <a href="#Constructors">octonion</a>(::boost::quaternion&lt;T&gt; const &amp; q0, ::boost::quaternion&lt;T&gt; const &amp; q1 = ::boost::quaternion&lt;T&gt;());
template&lt;typename X&gt; explicit <a href="#Constructors">octonion</a>(octonion&lt;X&gt; const &amp; a_recopier);
T <a href="#Other member functions">real</a>() const;
octonion&lt;T&gt; <a href="#Other member functions">unreal</a>() const;
T <a href="#Other member functions">R_component_1</a>() const;
T <a href="#Other member functions">R_component_2</a>() const;
T <a href="#Other member functions">R_component_3</a>() const;
T <a href="#Other member functions">R_component_4</a>() const;
T <a href="#Other member functions">R_component_5</a>() const;
T <a href="#Other member functions">R_component_6</a>() const;
T <a href="#Other member functions">R_component_7</a>() const;
T <a href="#Other member functions">R_component_8</a>() const;
::std::complex&lt;T&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;T&gt; <a href="#Other member functions">C_component_2</a>() const;
::std::complex&lt;T&gt; <a href="#Other member functions">C_component_3</a>() const;
::std::complex&lt;T&gt; <a href="#Other member functions">C_component_4</a>() const;
::boost::quaternion&lt;T&gt; <a href="#Other member functions">H_component_1</a>() const;
::boost::quaternion&lt;T&gt; <a href="#Other member functions">H_component_2</a>() const;
octonion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;T&gt; const &amp; a_affecter);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;X&gt; const &amp; a_affecter);
octonion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (T const &amp; a_affecter);
octonion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;T&gt; const &amp; a_affecter);
octonion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (::boost::quaternion&lt;T&gt; const &amp; a_affecter);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (T const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (T const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (T const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (T const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (octonion&lt;X&gt; const &amp; rhs);
}
}</code></pre>
<p></p>
<h2><a name="quaternion specializations"></a><code>octonion</code> specializations</h2>
<pre><code>namespace boost
{
<a name="octonion<float>"></a> template&lt;&gt;
class octonion&lt;float&gt;
{
public:
typedef float <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">octonion</a>(float const &amp; requested_a = 0.0f, float const &amp; requested_b = 0.0f, float const &amp; requested_c = 0.0f, float const &amp; requested_d = 0.0f, float const &amp; requested_e = 0.0f, float const &amp; requested_f = 0.0f, float const &amp; requested_g = 0.0f, float const &amp; requested_h = 0.0f);
explicit <a href="#Constructors">octonion</a>(::std::complex&lt;float&gt; const &amp; z0, ::std::complex&lt;float&gt; const &amp; z1 = ::std::complex&lt;float&gt;(), ::std::complex&lt;float&gt; const &amp; z2 = ::std::complex&lt;float&gt;(), ::std::complex&lt;float&gt; const &amp; z3 = ::std::complex&lt;float&gt;());
explicit <a href="#Constructors">octonion</a>(::boost::quaternion&lt;float&gt; const &amp; q0, ::boost::quaternion&lt;float&gt; const &amp; q1 = ::boost::quaternion&lt;float&gt;());
explicit <a href="#Constructors">octonion</a>(octonion&lt;double&gt; const &amp; a_recopier);
explicit <a href="#Constructors">octonion</a>(octonion&lt;long double&gt; const &amp; a_recopier);
float <a href="#Other member functions">real</a>() const;
octonion&lt;float&gt; <a href="#Other member functions">unreal</a>() const;
float <a href="#Other member functions">R_component_1</a>() const;
float <a href="#Other member functions">R_component_2</a>() const;
float <a href="#Other member functions">R_component_3</a>() const;
float <a href="#Other member functions">R_component_4</a>() const;
float <a href="#Other member functions">R_component_5</a>() const;
float <a href="#Other member functions">R_component_6</a>() const;
float <a href="#Other member functions">R_component_7</a>() const;
float <a href="#Other member functions">R_component_8</a>() const;
::std::complex&lt;float&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;float&gt; <a href="#Other member functions">C_component_2</a>() const;
::std::complex&lt;float&gt; <a href="#Other member functions">C_component_3</a>() const;
::std::complex&lt;float&gt; <a href="#Other member functions">C_component_4</a>() const;
::boost::octonion&lt;float&gt; <a href="#Other member functions">H_component_1</a>() const;
::boost::octonion&lt;float&gt; <a href="#Other member functions">H_component_2</a>() const;
octonion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;float&gt; const &amp; a_affecter);
template&lt;typename X&gt; octonion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;X&gt;const &amp; a_affecter);
octonion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (float const &amp; a_affecter);
octonion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;float&gt; const &amp; a_affecter);
octonion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (::boost::quaternion&lt;float&gt; const &amp; a_affecter);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator +=</a> (float const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;float&gt; &amp; <a href="#Other member operators">operator +=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (float const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;float&gt; const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (::boost::quaternion&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (float const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;float&gt; const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (::boost::quaternion&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (float const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;float&gt; const &amp; rhs);
octonion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (::boost::quaternion&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (octonion&lt;X&gt; const &amp; rhs);
};
<a name="octonion<double>"></a> template&lt;&gt;
class octonion&lt;double&gt;
{
public:
typedef double <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">octonion</a>(double const &amp; requested_a = 0.0, double const &amp; requested_b = 0.0, double const &amp; requested_c = 0.0, double const &amp; requested_d = 0.0, double const &amp; requested_e = 0.0, double const &amp; requested_f = 0.0, double const &amp; requested_g = 0.0, double const &amp; requested_h = 0.0);
explicit <a href="#Constructors">octonion</a>(::std::complex&lt;double&gt; const &amp; z0, ::std::complex&lt;double&gt; const &amp; z1 = ::std::complex&lt;double&gt;(), ::std::complex&lt;double&gt; const &amp; z2 = ::std::complex&lt;double&gt;(), ::std::complex&lt;double&gt; const &amp; z3 = ::std::complex&lt;double&gt;());
explicit <a href="#Constructors">octonion</a>(::boost::quaternion&lt;double&gt; const &amp; q0, ::boost::quaternion&lt;double&gt; const &amp; q1 = ::boost::quaternion&lt;double&gt;());
explicit <a href="#Constructors">octonion</a>(octonion&lt;float&gt; const &amp; a_recopier);
explicit <a href="#Constructors">octonion</a>(octonion&lt;long double&gt; const &amp; a_recopier);
double <a href="#Other member functions">real</a>() const;
octonion&lt;double&gt; <a href="#Other member functions">unreal</a>() const;
double <a href="#Other member functions">R_component_1</a>() const;
double <a href="#Other member functions">R_component_2</a>() const;
double <a href="#Other member functions">R_component_3</a>() const;
double <a href="#Other member functions">R_component_4</a>() const;
double <a href="#Other member functions">R_component_5</a>() const;
double <a href="#Other member functions">R_component_6</a>() const;
double <a href="#Other member functions">R_component_7</a>() const;
double <a href="#Other member functions">R_component_8</a>() const;
::std::complex&lt;double&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;double&gt; <a href="#Other member functions">C_component_2</a>() const;
::std::complex&lt;double&gt; <a href="#Other member functions">C_component_3</a>() const;
::std::complex&lt;double&gt; <a href="#Other member functions">C_component_4</a>() const;
::boost::quaternion&lt;double&gt; <a href="#Other member functions">H_component_1</a>() const;
::boost::quaternion&lt;double&gt; <a href="#Other member functions">H_component_2</a>() const;
octonion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;double&gt; const &amp; a_affecter);
template&lt;typename X&gt; octonion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;X&gt; const &amp; a_affecter);
octonion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (double const &amp; a_affecter);
octonion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;double&gt; const &amp; a_affecter);
octonion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (::boost::quaternion&lt;double&gt; const &amp; a_affecter);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (double const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;double&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (::boost::quaternion&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (double const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;double&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (::boost::quaternion&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (double const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;double&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (::boost::quaternion&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (double const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;double&gt; const &amp; rhs);
octonion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (::boost::quaternion&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (octonion&lt;X&gt; const &amp; rhs);
};
<a name="octonion<long double>"></a> template&lt;&gt;
class octonion&lt;long double&gt;
{
public:
typedef long double <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">octonion</a>(long double const &amp; requested_a = 0.0L, long double const &amp; requested_b = 0.0L, long double const &amp; requested_c = 0.0L, long double const &amp; requested_d = 0.0L, long double const &amp; requested_e = 0.0L, long double const &amp; requested_f = 0.0L, long double const &amp; requested_g = 0.0L, long double const &amp; requested_h = 0.0L);
explicit <a href="#Constructors">octonion</a>( ::std::complex&lt;long double&gt; const &amp; z0, ::std::complex&lt;long double&gt; const &amp; z1 = ::std::complex&lt;long double&gt;(), ::std::complex&lt;long double&gt; const &amp; z2 = ::std::complex&lt;long double&gt;(), ::std::complex&lt;long double&gt; const &amp; z3 = ::std::complex&lt;long double&gt;());
explicit <a href="#Constructors">octonion</a>( ::boost::quaternion&lt;long double&gt; const &amp; q0, ::boost::quaternion&lt;long double&gt; const &amp; z1 = ::boost::quaternion&lt;long double&gt;());
explicit <a href="#Constructors">octonion</a>(octonion&lt;float&gt; const &amp; a_recopier);
explicit <a href="#Constructors">octonion</a>(octonion&lt;double&gt; const &amp; a_recopier);
long double <a href="#Other member functions">real</a>() const;
octonion&lt;long double&gt; <a href="#Other member functions">unreal</a>() const;
long double <a href="#Other member functions">R_component_1</a>() const;
long double <a href="#Other member functions">R_component_2</a>() const;
long double <a href="#Other member functions">R_component_3</a>() const;
long double <a href="#Other member functions">R_component_4</a>() const;
long double <a href="#Other member functions">R_component_5</a>() const;
long double <a href="#Other member functions">R_component_6</a>() const;
long double <a href="#Other member functions">R_component_7</a>() const;
long double <a href="#Other member functions">R_component_8</a>() const;
::std::complex&lt;long double&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;long double&gt; <a href="#Other member functions">C_component_2</a>() const;
::std::complex&lt;long double&gt; <a href="#Other member functions">C_component_3</a>() const;
::std::complex&lt;long double&gt; <a href="#Other member functions">C_component_4</a>() const;
::boost::quaternion&lt;long double&gt; <a href="#Other member functions">H_component_1</a>() const;
::boost::quaternion&lt;long double&gt; <a href="#Other member functions">H_component_2</a>() const;
octonion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;long double&gt; const &amp; a_affecter);
template&lt;typename X&gt; octonion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (octonion&lt;X&gt; const &amp; a_affecter);
octonion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (long double const &amp; a_affecter);
octonion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;long double&gt; const &amp; a_affecter);
octonion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (::boost::quaternion&lt;long double&gt; const &amp; a_affecter);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (long double const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (::boost::quaternion&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (long double const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (::boost::quaternion&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (long double const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (::boost::quaternion&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (octonion&lt;X&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (long double const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (::boost::quaternion&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (octonion&lt;X&gt; const &amp; rhs);
};
}</code></pre>
<p></p>
<h2><a name="octonion typedefs"></a><code>octonion</code> typedefs</h2>
<h3><a name="value_type"></a><code>value_type</code></h3>
<pre><code>typedef T <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Template version.</p>
</blockquote>
<pre><code>typedef float <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Float specialization version.</p>
</blockquote>
<pre><code>typedef double <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Double specialization version.</p>
</blockquote>
<pre><code>typedef long double <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Long double specialization version.</p>
<p>These provide easy acces to the type the template is built upon.</p>
</blockquote>
<h2><a name="octonion member functions"></a><code>octonion</code> member functions</h2>
<h3><a name="Constructors"></a>Constructors</h3>
<pre><code>explicit <strong>octonion</strong>(T const &amp; requested_a = T(), T const &amp; requested_b = T(), T const &amp; requested_c = T(), T const &amp; requested_d = T(), T const & requested_e = T(), T const & requested_f = T(), T const & requested_g = T(), T const & requested_h = T());
explicit <strong>octonion</strong>(::std::complex&lt;T&gt; const &amp; z0, ::std::complex&lt;T&gt; const &amp; z1 = ::std::complex&lt;T&gt;(), ::std::complex&lt;T&gt; const & z2 = ::std::complex&lt;T&gt;(), ::std::complex&lt;T&gt; const & z3 = ::std::complex&lt;T&gt;());
explicit <strong>octonion</strong>(::boost::quaternion&lt;T&gt; const &amp; q0, ::boost::quaternion&lt;T&gt; const &amp; q1 = ::boost::quaternion&lt;T&gt;());
template&lt;typename X&gt; explicit <strong>octonion</strong>(octonion&lt;X&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Template version.</p>
</blockquote>
<pre><code>explicit <strong>octonion</strong>(float const &amp; requested_a = 0.0f, float const &amp; requested_b = 0.0f, float const &amp; requested_c = 0.0f, float const &amp; requested_d = 0.0f, float const &amp; requested_e = 0.0f, float const &amp; requested_f = 0.0f, float const &amp; requested_g = 0.0f, float const &amp; requested_h = 0.0f);
explicit <strong>octonion</strong>(::std::complex&lt;float&gt; const &amp; z0, ::std::complex&lt;float&gt; const &amp; z1 = ::std::complex&lt;float&gt;(), ::std::complex&lt;float&gt; const &amp; z2 = ::std::complex&lt;float&gt;(), ::std::complex&lt;float&gt; const &amp; z3 = ::std::complex&lt;float&gt;());
explicit <strong>octonion</strong>(::boost::quaternion&lt;float&gt; const &amp; q0, ::boost::quaternion&lt;float&gt; const &amp; q1 = ::boost::quaternion&lt;float&gt;());
explicit <strong>octonion</strong>(octonion&lt;double&gt; const &amp; a_recopier);
explicit <strong>octonion</strong>(octonion&lt;long double&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Float specialization version.</p>
</blockquote>
<pre><code>explicit <strong>octonion</strong>(double const &amp; requested_a = 0.0, double const &amp; requested_b = 0.0, double const &amp; requested_c = 0.0, double const &amp; requested_d = 0.0, double const &amp; requested_e = 0.0, double const &amp; requested_f = 0.0, double const &amp; requested_g = 0.0, double const &amp; requested_h = 0.0);
explicit <strong>octonion</strong>(::std::complex&lt;double&gt; const &amp; z0, ::std::complex&lt;double&gt; const &amp; z1 = ::std::complex&lt;double&gt;(), ::std::complex&lt;double&gt; const &amp; z2 = ::std::complex&lt;double&gt;(), ::std::complex&lt;double&gt; const &amp; z3 = ::std::complex&lt;double&gt;());
explicit <strong>octonion</strong>(::boost::quaternion&lt;double&gt; const &amp; q0, ::boost::quaternion&lt;double&gt; const &amp; q1 = ::boost::quaternion&lt;double&gt;());
explicit <strong>octonion</strong>(octonion&lt;float&gt; const &amp; a_recopier);
explicit <strong>octonion</strong>(octonion&lt;long double&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Double specialization version.</p>
</blockquote>
<pre><code>explicit <strong>octonion</strong>(long double const &amp; requested_a = 0.0L, long double const &amp; requested_b = 0.0L, long double const &amp; requested_c = 0.0L, long double const &amp; requested_d = 0.0L, long double const &amp; requested_e = 0.0L, long double const &amp; requested_f = 0.0L, long double const &amp; requested_g = 0.0L, long double const &amp; requested_h = 0.0L);
explicit <strong>octonion</strong>( ::std::complex&lt;long double&gt; const &amp; z0, ::std::complex&lt;long double&gt; const &amp; z1 = ::std::complex&lt;long double&gt;(), ::std::complex&lt;long double&gt; const &amp; z2 = ::std::complex&lt;long double&gt;(), ::std::complex&lt;long double&gt; const &amp; z3 = ::std::complex&lt;long double&gt;());
explicit <strong>octonion</strong>(::boost::quaternion&lt;long double&gt; const &amp; q0, ::boost::quaternion&lt;long double&gt; const &amp; q1 = ::boost::quaternion&lt;long double&gt;());
explicit <strong>octonion</strong>(octonion&lt;float&gt; const &amp; a_recopier);
explicit <strong>octonion</strong>(octonion&lt;double&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Long double specialization version.</p>
<p>A default constructor is provided for each form, which initializes each component to the default values for their type (<cite>i.e.</cite> zero for floating numbers). This constructor can also accept one to eight base type arguments. A constructor is also provided to build octonions from one to four complex numbers sharing the same base type, and another taking one or two quaternionssharing the same base type. The unspecialized template also sports a templarized copy constructor, while the specialized forms have copy constructors from the other two specializations, which are explicit when a risk of precision loss exists. For the unspecialized form, the base type's constructors must not throw.</p>
<p>Destructors and untemplated copy constructors (from the same type) are provided by the compiler.</p>
</blockquote>
<h3><a name="Other member functions"></a>Other member functions</h3>
<pre><code>T <strong>real</strong>() const;
octonion&lt;T&gt; <strong>unreal</strong>() const;</code></pre>
<blockquote>
<p>Like complex number, octonions do have a meaningful notion of &quot;real part&quot;, but unlike them there is no meaningful notion of &quot;imaginary part&quot;. Instead there is an &quot;unreal part&quot; which itself is a octonion, and usually nothing simpler (as opposed to the complex number case). These are returned by the first two functions.</p>
</blockquote>
<pre><code>T <strong>R_component_1</strong>() const;
T <strong>R_component_2</strong>() const;
T <strong>R_component_3</strong>() const;
T <strong>R_component_4</strong>() const;
T <strong>R_component_5</strong>() const;
T <strong>R_component_6</strong>() const;
T <strong>R_component_7</strong>() const;
T <strong>R_component_8</strong>() const;</code></pre>
<blockquote>
<p>A octonion having eight real components, these are returned by these eight functions. Hence <code>real</code> and <code>R_component_1</code> return the same value.</p>
</blockquote>
<pre><code>::std::complex&lt;T&gt; <strong>C_component_1</strong>() const;
::std::complex&lt;T&gt; <strong>C_component_2</strong>() const;
::std::complex&lt;T&gt; <strong>C_component_3</strong>() const;
::std::complex&lt;T&gt; <strong>C_component_4</strong>() const;</code></pre>
<blockquote>
<p>A octonion likewise has four complex components. Actually, <font color="#000000">octonions are indeed a (left) vector field over the complexes</font>, but <em>beware</em>, as <font color="#000000">for any octonion <img src="graphics/octonion_blurb.html18.jpeg" width="215" height="15" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> we also have <img src="graphics/octonion_blurb.html19.jpeg" width="228" height="17" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> (note the <strong>minus</strong> sign in the last factor)</font><font color="#000000">. What the <code>C_component_n</code> functions return, however, are the complexes which could be used to build the octonion using the constructor, and <strong>not</strong> the components of the octonion on the basis <img src="graphics/octonion_blurb.html21.jpeg" width="52" height="16" naturalsizeflag="3" align=absmiddle></font><font color="#000000">.</font></p>
</blockquote>
<pre><code>::boost::quaternion&lt;T&gt; <strong>H_component_1</strong>() const;
::boost::quaternion&lt;T&gt; <strong>H_component_2</strong>() const;</code></pre>
<blockquote>
<p>Likewise, for any octonion <img src="graphics/octonion_blurb.html18.jpeg" width="215" height="15" naturalsizeflag="3" align=absmiddle> we also have<font color="#000000"> <img src="graphics/octonion_blurb.html20.jpeg" width="219" height="17" naturalsizeflag="3" align=absmiddle>, though there is no meaningful vector-space-like structure based on the quaternions. What the <code>H_component_n</code> functions return are the quaternions which could be used to build the octonion</font><font color="#000000"> using the constructor.</font></p>
</blockquote>
<h2><a name="octonion member operators"></a><code>octonion</code> member operators</h2>
<h3><a name="Assignment operators"></a>Assignment operators</h3>
<pre><code>octonion&lt;T&gt; &amp; <strong>operator =</strong> (octonion&lt;T&gt; const &amp; a_affecter);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <strong>operator =</strong> (octonion&lt;X&gt; const &amp; a_affecter);
octonion&lt;T&gt; &amp; <strong>operator =</strong> (T const &amp; a_affecter);
octonion&lt;T&gt; &amp; <strong>operator =</strong> (::std::complex&lt;T&gt; const &amp; a_affecter);
octonion&lt;T&gt; &amp; <strong>operator =</strong> (::boost::quaternion&lt;T&gt; const &amp; a_affecter);</code></pre>
<blockquote>
<p>These perform the expected assignment, with type modification if necessary (for instance, assigning from a base type will set the real part to that value, and all other components to zero). For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<h3><a name="Other member operators"></a>Other member operators</h3>
<pre><code>octonion&lt;T&gt; &amp; <strong>operator +=</strong> (T const &amp; rhs)
octonion&lt;T&gt; &amp; <strong>operator +=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <strong>operator +=</strong> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <strong>operator +=</strong> (octonion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)+rhs and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<pre><code>octonion&lt;T&gt; &amp; <strong>operator -=</strong> (T const &amp; rhs)
octonion&lt;T&gt; &amp; <strong>operator -=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <strong>operator -=</strong> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <strong>operator -=</strong> (octonion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)-rhs and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<pre><code>octonion&lt;T&gt; &amp; <strong>operator *=</strong> (T const &amp; rhs)
octonion&lt;T&gt; &amp; <strong>operator *=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <strong>operator *=</strong> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <strong>operator *=</strong> (octonion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)*rhs <strong>in this order</strong> (order is important as multiplication is not commutative for octonions) and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw. Also, for clarity's sake, you should <em>always</em> group the factors in a multiplication by groups of two, as the multiplication is not even associative on the octonions (though there are of course cases where this does not matter, it usually does).</p>
</blockquote>
<pre><code>octonion&lt;T&gt; &amp; <strong>operator /=</strong> (T const &amp; rhs)
octonion&lt;T&gt; &amp; <strong>operator /=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
octonion&lt;T&gt; &amp; <strong>operator /=</strong> (::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; octonion&lt;T&gt; &amp; <strong>operator /=</strong> (octonion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)*inverse_of(rhs) <strong>in this order</strong> (order is important as multiplication is not commutative for octonions) and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw. As for the multiplication, remember to group any two factors using parenthesis.</p>
</blockquote>
<h2><a name="octonion non-member operations"></a><code>octonion</code> non-member operations</h2>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>This unary operator simply returns <code>o</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>This unary operator returns the opposite of <code>o</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator +</strong> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>octonion&lt;T&gt;(lhs) += rhs</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator -</strong> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>octonion&lt;T&gt;(lhs) -= rhs</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator *</strong> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>octonion&lt;T&gt;(lhs) *= rhs</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>operator /</strong> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>octonion&lt;T&gt;(lhs) /= rhs</code>. It is of course still an error to divide by zero...</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline bool <strong>operator ==</strong> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These return <code>true</code> if and only if the four components of <code>octonion&lt;T&gt;(lhs)</code> are equal to their counterparts in <code>octonion&lt;T&gt;(rhs)</code>. As with any floating-type entity, this is essentially meaningless.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline bool <strong>operator !=</strong> (T const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (octonion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (::std::complex&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (octonion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (::boost::quaternion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (octonion&lt;T&gt; const &amp; lhs, ::boost::quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (octonion&lt;T&gt; const &amp; lhs, octonion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These return <code>true</code> if and only if <code>octonion&lt;T&gt;(lhs) == octonion&lt;T&gt;(rhs)</code> is <code>false</code>. As with any floating-type entity, this is essentially meaningless.</p>
</blockquote>
<pre><code>template&lt;typename T, typename charT, class traits&gt;
::std::basic_istream&lt;charT,traits&gt; &amp; <strong>operator &gt;&gt;</strong> (::std::basic_istream&lt;charT,traits&gt; &amp; is, octonion&lt;T&gt; &amp; o);</code></pre>
<blockquote>
<p>Extracts an octonion <code>o</code>. We accept any format which seems reasonable. However, since this leads to a great many ambiguities, decisions were made to lift these. In case of doubt, stick to lists of reals.</p>
<p>The input values must be convertible to T. If bad input is encountered, calls is.setstate(ios::failbit) (which may throw ios::failure (27.4.5.3)).</p>
<p>Returns <code>is</code>.</p>
</blockquote>
<pre><code>template&lt;typename T, typename charT, class traits&gt;
::std::basic_ostream&lt;charT,traits&gt; &amp; <strong>operator &lt;&lt;</strong> (::std::basic_ostream&lt;charT,traits&gt; &amp; os, octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Inserts the octonion <code>o</code> onto the stream <code>os</code> as if it were implemented as follows (which it actually is):</p>
</blockquote>
<pre><code> template&lt;typename T, typename charT, class traits&gt;
::std::basic_ostream&lt;charT,traits&gt; &amp; operator &lt;&lt; ( ::std::basic_ostream&lt;charT,traits&gt; &amp; os,
octonion&lt;T&gt; const &amp; o)
{
::std::basic_ostringstream&lt;charT,traits&gt; s;
s.flags(os.flags());
s.imbue(os.getloc());
s.precision(os.precision());
s &lt;&lt; '(' &lt;&lt; o.R_component_1() &lt;&lt; ','
&lt;&lt; o.R_component_2() &lt;&lt; ','
&lt;&lt; o.R_component_3() &lt;&lt; ','
&lt;&lt; o.R_component_4() &lt;&lt; ','
&lt;&lt; o.R_component_5() &lt;&lt; ','
&lt;&lt; o.R_component_6() &lt;&lt; ','
&lt;&lt; o.R_component_7() &lt;&lt; ','
&lt;&lt; o.R_component_8() &lt;&lt; ')' &lt;&lt; ::std::ends;
return os &lt;&lt; s.str();
}</code></pre>
<h2><a name="octonion value operations"></a><code>octonion</code> value operations</h2>
<pre><code>template&lt;typename T&gt; inline T <strong>real</strong>(octonion&lt;T&gt; const &amp; o);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>unreal</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>These return <code>o.real()</code> and <code>o.unreal()</code> respectively.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>conj</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>This returns the conjugate of the octonion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>sup</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>This return the sup norm (the greatest among <code>abs(o.R_component_1())</code>...<code>abs(o.R_component_8())</code>) of the octonion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>l1</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>This return the l1 norm (<code>abs(o.R_component_1())+...+abs(o.R_component_8())</code>) of the octonion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>abs</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>This return the magnitude (Euclidian norm) of the octonion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>norm</strong>(octonion&lt;T&gt;const &amp; o);</code></pre>
<blockquote>
<p>This return the (Cayley) norm of the octonion. The term &quot;norm&quot; might be confusing, as most people associate it with the Euclidian norm (and quadratic functionals). For this version of (the mathematical objects known as) octonions, the Euclidian norm (also known as magnitude) is the square root of the Cayley norm.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>spherical</strong>(T const &amp; rho, T const &amp; theta, T const &amp; phi1, T const &amp; phi2, T const &amp; phi3, T const &amp; phi4, T const &amp; phi5, T const &amp; phi6);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>multipolar</strong>(T const &amp; rho1, T const &amp; theta1, T const &amp; rho2, T const &amp; theta2, T const &amp; rho3, T const &amp; theta3, T const &amp; rho4, T const &amp; theta4);
template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>cylindrical</strong>(T const &amp; r, T const &amp; angle, T const &amp; h1, T const &amp; h2, T const &amp; h3, T const &amp; h4, T const &amp; h5, T const &amp; h6);</code></pre>
<blockquote>
<p>These build octonions in a way similar to the way <code>polar</code> builds complex numbers, as there is no strict equivalent to polar coordinates for octonions.</p>
<p><code>spherical</code> is a simple transposition of <code>polar</code>, it takes as inputs a (positive) magnitude and a point on the hypersphere, given by three angles. The first of these, <code>theta</code> has a natural range of -pi to +pi, and the other two have natural ranges of -pi/2 to +pi/2 (as is the case with the usual spherical coordinates in R^3). Due to the many symmetries and periodicities, nothing untoward happens if the magnitude is negative or the angles are outside their natural ranges. The expected degeneracies (a magnitude of zero ignores the angles settings...) do happen however.</p>
<p><code>cylindrical</code> is likewise a simple transposition of the usual cylindrical coordinates in R^3, which in turn is another derivative of planar polar coordinates. The first two inputs are the polar coordinates of the first C component of the octonion. The third and fourth inputs are placed into the third and fourth R components of the octonion, respectively.</p>
<p><code>multipolar</code> is yet another simple generalization of polar coordinates. This time, both C components of the octonion are given in polar coordinates.</p>
</blockquote>
<p>In this version of our implementation of octonions, there is no analogue of the complex value operation <code>arg</code> as the situation is somewhat more complicated.</p>
<h2><a name="octonion transcendentals"></a><code>octonion</code> transcendentals</h2>
<p>There is no <code>log</code> or <code>sqrt</code> provided for octonions in this implementation, and <code>pow</code> is likewise restricted to integral powers of the exponent. There are several reasons to this: on the one hand, the equivalent of analytic continuation for octonions (&quot;branch cuts&quot;) remains to be investigated thoroughly (by me, at any rate...), and we wish to avoid the nonsense introduced in the standard by exponentiations of complexes by complexes (which is well defined, but not in the standard...). Talking of nonsense, saying that <code>pow(0,0)</code> is &quot;implementation defined&quot; is just plain brain-dead...</p>
<p>We do, however provide several transcendentals, chief among which is the exponential. That it allows for a &quot;closed formula&quot; is a result of the author (the existence and definition of the exponential, on the octonions among others, on the other hand, is a few centuries old). Basically, any converging power series with real coefficients which allows for a closed formula in C can be transposed to O. More transcendentals of this type could be added in a further revision upon request. It should be noted that it is these functions which force the dependency upon the <a href="../../../boost/math/special_functions/sinc.hpp">boost/math/<code>special_functions/sinc.hpp</code></a> and the <a href="../../../boost/math/special_functions/sinhc.hpp">boost/math/<code>special_functions/sinhc.hpp</code></a> headers.</p>
<h3><a name="exp"></a>exp</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>exp</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the exponential of the octonion.</p>
</blockquote>
<h3><a name="cos"></a>cos</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>cos</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the cosine of the octonion</p>
</blockquote>
<h3><a name="sin"></a>sin</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>sin</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the sine of the octonion.</p>
</blockquote>
<h3><a name="tan"></a>tan</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>tan</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the tangent of the octonion.</p>
</blockquote>
<h3><a name="cosh"></a>cosh</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>cosh</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the hyperbolic cosine of the octonion.</p>
</blockquote>
<h3><a name="sinh"></a>sinh</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>sinh</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the hyperbolic sine of the octonion.</p>
</blockquote>
<h3><a name="tanh"></a>tanh</h3>
<pre><code>template&lt;typename T&gt; inline octonion&lt;T&gt; <strong>tanh</strong>(octonion&lt;T&gt; const &amp; o);</code></pre>
<blockquote>
<p>Computes the hyperbolic tangent of the octonion.</p>
</blockquote>
<h3><a name="pow"></a>pow</h3>
<pre><code>template&lt;typename T&gt; octonion&lt;T&gt; <strong>pow</strong>(octonion&lt;T&gt; const &amp; o, int n);</code></pre>
<blockquote>
<p>Computes the <code>n</code>-th power of the octonion <code>q</code>.</p>
</blockquote>
<h2><a name="History"></a>History</h2>
<ul>
<li>1.5.1 - 07/06/2001: (end of Boost review) now includes <code>&lt;boost/math/special_functions/sinc.hpp&gt;</code> and <code>&lt;boost/math/special_functions/sinhc.hpp&gt;</code> instead of <code>&lt;boost/special_functions.hpp&gt;</code>; corrected bug in <code>sin</code> (Daryle Walker); removed check for self-assignment (Gary Powel); made converting functions <code>explicit</code> (Gary Powel); added overflow guards for division operators and <code>abs</code> (Peter Schmitteckert); added <code>sup</code> and <code>l1</code>; used Vesa Karvonen's CPP metaprograming technique to simplify code.
<li>1.5.0 - 23/03/2001: boostification, inlining of all operators except input, output and <code>pow</code>, fixed exception safety of some members (template version).
<li>1.4.0 - 09/01/2001: added <code>tan</code> and <code>tanh</code>. <li>1.3.1 - 08/01/2001: cosmetic fixes.
<li>1.3.0 - 12/07/2000: <code>pow</code> now uses Maarten Hilferink's (mhilferink@tip.nl) algorithm. <li>1.2.0 - 25/05/2000: fixed the division operators and output; changed many signatures. <li>1.1.0 - 23/05/2000: changed <code>sinc</code> into <code>sinc_pi</code>; added <code>sin</code>, <code>cos</code>, <code>sinh</code>, <code>cosh</code>. <li>1.0.0 - 10/08/1999: first public version.
</ul>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 June 2001<!--webbot bot="Timestamp" endspan i-checksum="32118" --></p>
<p>&copy; Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This software is provided &quot;as is&quot; without express or implied&nbsp; warranty, and with no claim as to its suitability for any purpose.</p>
</body>
</html>

692
octonion/octonion_test.cpp Normal file
View File

@@ -0,0 +1,692 @@
// test file for octonion.hpp
// (C) Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#define BOOST_INTERACTIVE_TEST_INPUT_ITERATOR 0
#include <iostream>
#include <boost/math/octonion.hpp>
// explicit (if ludicrous) instanciation
#ifndef __GNUC__
template class ::boost::octonion<int>;
#else
// gcc 3.0 doesn't like the absolutely-qualified namespace
template class boost::octonion<int>;
#endif
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
#include <boost/test/test_tools.hpp>
int test_main(int, char *[])
{
// tests for evaluation by humans
// using default constructor
::boost::octonion<float> o0;
::boost::octonion<float> oa[2];
// using constructor "O seen as R^8"
::boost::octonion<float> o1(1,2,3,4,5,6,7,8);
::std::complex<double> c0(9,10);
// using constructor "O seen as C^4"
::boost::octonion<double> o2(c0);
::boost::quaternion<long double> q0(11,12,13,14);
// using constructor "O seen as H^2"
::boost::octonion<long double> o3(q0);
// using UNtemplated copy constructor
::boost::octonion<float> o4(o1);
// using templated copy constructor
::boost::octonion<long double> o5(o2);
// using UNtemplated assignment operator
o5 = o3;
// using templated assignment operator
o5 = o2;
float f0(15);
// using converting assignment operator
o0 = f0;
// using converting assignment operator
o2 = c0;
// using converting assignment operator
o5 = q0;
// using += (const T &)
o4 += f0;
// using += (const ::std::complex<T> &)
o2 += c0;
// using += (const ::boost::quaternion<T> &)
o3 += q0;
// using += (const quaternion<X> &)
o5 += o4;
// using -= (const T &)
o1 -= f0;
// using -= (const ::std::complex<T> &)
o2 -= c0;
// using -= (const ::boost::quaternion<T> &)
o5 -= q0;
// using -= (const octonion<X> &)
o3 -= o4;
double d0(16);
::std::complex<double> c1(17,18);
::boost::quaternion<double> q1(19,20,21,22);
// using *= (const T &)
o2 *= d0;
// using *= (const ::std::complex<T> &)
o2 *= c1;
// using *= (const ::boost::quaternion<T> &)
o2 *= q1;
// using *= (const octonion<X> &)
o2 *= o4;
long double l0(23);
::std::complex<long double> c2(24,25);
// using /= (const T &)
o5 /= l0;
// using /= (const ::std::complex<T> &)
o5 /= c2;
// using /= (const quaternion<X> &)
o5 /= q0;
// using /= (const octonion<X> &)
o5 /= o5;
// using + (const T &, const octonion<T> &)
::boost::octonion<float> o6 = f0+o0;
// using + (const octonion<T> &, const T &)
::boost::octonion<float> o7 = o0+f0;
// using + (const ::std::complex<T> &, const quaternion<T> &)
::boost::octonion<double> o8 = c0+o2;
// using + (const octonion<T> &, const ::std::complex<T> &)
::boost::octonion<double> o9 = o2+c0;
// using + (const ::boost::quaternion<T>, const octonion<T> &)
::boost::octonion<long double> o10 = q0+o3;
// using + (const octonion<T> &, const ::boost::quaternion<T> &)
::boost::octonion<long double> o11 = o3+q0;
// using + (const quaternion<T> &,const quaternion<T> &)
::boost::octonion<float> o12 = o0+o4;
// using - (const T &, const octonion<T> &)
o6 = f0-o0;
// using - (const octonion<T> &, const T &)
o7 = o0-f0;
// using - (const ::std::complex<T> &, const octonion<T> &)
o8 = c0-o2;
// using - (const octonion<T> &, const ::std::complex<T> &)
o9 = o2-c0;
// using - (const quaternion<T> &,const octonion<T> &)
o10 = q0-o3;
// using - (const octonion<T> &,const quaternion<T> &)
o11 = o3-q0;
// using - (const octonion<T> &,const octonion<T> &)
o12 = o0-o4;
// using * (const T &, const octonion<T> &)
o6 = f0*o0;
// using * (const octonion<T> &, const T &)
o7 = o0*f0;
// using * (const ::std::complex<T> &, const octonion<T> &)
o8 = c0*o2;
// using * (const octonion<T> &, const ::std::complex<T> &)
o9 = o2*c0;
// using * (const quaternion<T> &,const octonion<T> &)
o10 = q0*o3;
// using * (const octonion<T> &,const quaternion<T> &)
o11 = o3*q0;
// using * (const octonion<T> &,const octonion<T> &)
o12 = o0*o4;
// using / (const T &, const octonion<T> &)
o6 = f0/o0;
// using / (const octonion<T> &, const T &)
o7 = o0/f0;
// using / (const ::std::complex<T> &, const octonion<T> &)
o8 = c0/o2;
// using / (const octonion<T> &, const ::std::complex<T> &)
o9 = o2/c0;
// using / (const ::boost::quaternion<T> &, const octonion<T> &)
o10 = q0/o3;
// using / (const octonion<T> &, const ::boost::quaternion<T> &)
o11 = o3/q0;
// using / (const octonion<T> &,const octonion<T> &)
o12 = o0/o4;
// using + (const octonion<T> &)
o4 = +o0;
// using - (const octonion<T> &)
o0 = -o4;
// using == (const T &, const octonion<T> &)
f0 == o0;
// using == (const octonion<T> &, const T &)
o0 == f0;
// using == (const ::std::complex<T> &, const octonion<T> &)
c0 == o2;
// using == (const octonion<T> &, const ::std::complex<T> &)
o2 == c0;
// using == (const ::boost::quaternion<T> &, const octonion<T> &)
q0 == o3;
// using == (const octonion<T> &, const ::boost::quaternion<T> &)
o3 == q0;
// using == (const octonion<T> &,const octonion<T> &)
o0 == o4;
// using != (const T &, const octonion<T> &)
f0 != o0;
// using != (const octonion<T> &, const T &)
o0 != f0;
// using != (const ::std::complex<T> &, const octonion<T> &)
c0 != o2;
// using != (const octonion<T> &, const ::std::complex<T> &)
o2 != c0;
// using != (const ::boost::quaternion<T> &, const octonion<T> &)
q0 != o3;
// using != (const octonion<T> &, const ::boost::quaternion<T> &)
o3 != q0;
// using != (const octonion<T> &,const octonion<T> &)
o0 != o4;
::std::cout << "Please input an octonion..." << ::std::endl;
#if BOOST_INTERACTIVE_TEST_INPUT_ITERATOR
::std::cin >> o0;
if (::std::cin.fail())
{
::std::cout << "You have entered nonsense!" << ::std::endl;
}
else
{
::std::cout << "You have entered the octonion "
<< o0 << " ." << ::std::endl;
}
#else
::std::istringstream bogus("(1,2,3,4,5,6,7,8)");
bogus >> o0;
::std::cout << "You have entered the octonion "
<< o0 << " ." << ::std::endl;
#endif
::std::cout << "For this octonion:" << ::std::endl;
::std::cout << "the value of "
<< "the real part is "
<< real(o0) << ::std::endl;
::std::cout << "the value of "
<< "the unreal part is "
<< unreal(o0) << ::std::endl;
::std::cout << "the value of "
<< "the sup norm is "
<< sup(o0) << ::std::endl;
::std::cout << "the value of "
<< "the l1 norm is "
<< l1(o0) << ::std::endl;
::std::cout << "the value of "
<< "the magnitude (euclidian norm) is "
<< abs(o0) << ::std::endl;
::std::cout << "the value of "
<< "the (Cayley) norm is "
<< norm(o0) << ::std::endl;
::std::cout << "the value of "
<< "the conjugate is "
<< conj(o0) << ::std::endl;
::std::cout << "the value of "
"the exponential is "
<< exp(o0) << ::std::endl;
::std::cout << "the value of "
<< "the cube is "
<< pow(o0,3) << ::std::endl;
::std::cout << "the value of "
<< "the cosinus is "
<< cos(o0) << ::std::endl;
::std::cout << "the value of "
<< "the sinus is "
<< sin(o0) << ::std::endl;
::std::cout << "the value of "
<< "the tangent is "
<< tan(o0) << ::std::endl;
::std::cout << "the value of "
<< "the hyperbolic cosinus is "
<< cosh(o0) << ::std::endl;
::std::cout << "the value of "
<< "the hyperbolic sinus is "
<< sinh(o0) << ::std::endl;
::std::cout << "the value of "
<< "the hyperbolic tangent is "
<< tanh(o0) << ::std::endl;
#if !defined(__GNUC__) && !defined(__COMO__)
// somehow, this does not work with either gcc or Comeau :-(
::std::cout << "the value of "
<< "the Sinus Cardinal (of index pi) is "
<< sinc_pi(o0) << ::std::endl;
::std::cout << "the value of "
<< "the Hyperbolic Sinus Cardinal (of index pi) is "
<< sinhc_pi(o0) << ::std::endl;
#endif
::std::cout << ::std::endl;
float rho = ::std::sqrt(4096.0f);
float theta = ::std::atan(1.0f);
float phi1 = ::std::atan(1.0f);
float phi2 = ::std::atan(1.0f);
float phi3 = ::std::atan(1.0f);
float phi4 = ::std::atan(1.0f);
float phi5 = ::std::atan(1.0f);
float phi6 = ::std::atan(1.0f);
::std::cout << "The value of the octonion represented "
<< "in spherical form by "
<< "rho = " << rho << " , theta = " << theta
<< " , phi1 = " << phi1 << " , phi2 = " << phi2
<< " , phi3 = " << phi3 << " , phi4 = " << phi4
<< " , phi5 = " << phi5 << " , phi6 = " << phi6
<< " is "
<< ::boost::spherical(rho, theta,
phi1, phi2, phi3, phi4, phi5, phi6)
<< ::std::endl;
float rho1 = 1;
float rho2 = 2;
float rho3 = ::std::sqrt(2.0f);
float rho4 = ::std::sqrt(8.0f);
float theta1 = 0;
float theta2 = ::std::atan(1.0f)*2;
float theta3 = ::std::atan(1.0f);
float theta4 =
::std::atan(::std::sqrt(3.0f));
::std::cout << "The value of the octonion represented "
<< "in multipolar form by "
<< "rho1 = " << rho1 << " , theta1 = " << theta1
<< " , rho2 = " << rho2 << " , theta2 = " << theta2
<< "rho3 = " << rho3 << " , theta3 = " << theta3
<< " , rho4 = " << rho4 << " , theta4 = " << theta4
<< " is "
<< ::boost::multipolar(rho1, theta1, rho2, theta2,
rho3, theta3, rho4, theta4)
<< ::std::endl;
float r = ::std::sqrt(2.0f);
float angle = ::std::atan(1.0f);
float h1 = 3;
float h2 = 4;
float h3 = 5;
float h4 = 6;
float h5 = 7;
float h6 = 8;
::std::cout << "The value of the octonion represented "
<< "in cylindrical form by "
<< "r = " << r << " , angle = " << angle
<< " , h1 = " << h1 << " , h2 = " << h2
<< " , h3 = " << h3 << " , h4 = " << h4
<< " , h5 = " << h5 << " , h6 = " << h6
<< " is " << ::boost::cylindrical(r, angle,
h1, h2, h3, h4, h5, h6)
<< ::std::endl;
double real_1(1);
::std::complex<double> complex_1(1);
::std::complex<double> complex_i(0,1);
::boost::quaternion<double> quaternion_1(1);
::boost::quaternion<double> quaternion_i(0,1);
::boost::quaternion<double> quaternion_j(0,0,1);
::boost::quaternion<double> quaternion_k(0,0,0,1);
::boost::octonion<double> octonion_1(1);
::boost::octonion<double> octonion_i(0,1);
::boost::octonion<double> octonion_j(0,0,1);
::boost::octonion<double> octonion_k(0,0,0,1);
::boost::octonion<double> octonion_e_prime(0,0,0,0,1);
::boost::octonion<double> octonion_i_prime(0,0,0,0,0,1);
::boost::octonion<double> octonion_j_prime(0,0,0,0,0,0,1);
::boost::octonion<double> octonion_k_prime(0,0,0,0,0,0,0,1);
::std::cout << ::std::endl;
::std::cout << "Real 1: " << real_1
<< " ; Complex 1: " << complex_1
<< " ; Quaternion 1: " << quaternion_1
<< " ; Octonion 1: " << octonion_1
<< " ." << ::std::endl;
::std::cout << "Complex i: " << complex_i
<< " ; Quaternion i: " << quaternion_i
<< " ; Octonion i : " << octonion_i
<< " ." << ::std::endl;
::std::cout << "Quaternion j: " << quaternion_j
<< " ; Octonion j: " << octonion_j
<< " ." << ::std::endl;
::std::cout << "Quaternion k: " << quaternion_k
<< " ; Octonion k: " << octonion_k
<< " ." << ::std::endl;
::std::cout << "Quaternion e\': " << octonion_e_prime
<< " ." << ::std::endl;
::std::cout << "Quaternion i\': " << octonion_i_prime
<< " ." << ::std::endl;
::std::cout << "Quaternion j\': " << octonion_j_prime
<< " ." << ::std::endl;
::std::cout << "Quaternion k\': " << octonion_k_prime
<< " ." << ::std::endl;
::std::cout << ::std::endl;
::std::cout << octonion_1*octonion_1 << " ; ";
::std::cout << octonion_1*octonion_i << " ; ";
::std::cout << octonion_1*octonion_j << " ; ";
::std::cout << octonion_1*octonion_k << " ; ";
::std::cout << octonion_1*octonion_e_prime << " ; ";
::std::cout << octonion_1*octonion_i_prime << " ; ";
::std::cout << octonion_1*octonion_j_prime << " ; ";
::std::cout << octonion_1*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_i*octonion_1 << " ; ";
::std::cout << octonion_i*octonion_i << " ; ";
::std::cout << octonion_i*octonion_j << " ; ";
::std::cout << octonion_i*octonion_k << " ; ";
::std::cout << octonion_i*octonion_e_prime << " ; ";
::std::cout << octonion_i*octonion_i_prime << " ; ";
::std::cout << octonion_i*octonion_j_prime << " ; ";
::std::cout << octonion_i*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_j*octonion_1 << " ; ";
::std::cout << octonion_j*octonion_i << " ; ";
::std::cout << octonion_j*octonion_j << " ; ";
::std::cout << octonion_j*octonion_k << " ; ";
::std::cout << octonion_j*octonion_e_prime << " ; ";
::std::cout << octonion_j*octonion_i_prime << " ; ";
::std::cout << octonion_j*octonion_j_prime << " ; ";
::std::cout << octonion_j*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_k*octonion_1 << " ; ";
::std::cout << octonion_k*octonion_i << " ; ";
::std::cout << octonion_k*octonion_j << " ; ";
::std::cout << octonion_k*octonion_k << " ; ";
::std::cout << octonion_k*octonion_e_prime << " ; ";
::std::cout << octonion_k*octonion_i_prime << " ; ";
::std::cout << octonion_k*octonion_j_prime << " ; ";
::std::cout << octonion_k*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_e_prime*octonion_1 << " ; ";
::std::cout << octonion_e_prime*octonion_i << " ; ";
::std::cout << octonion_e_prime*octonion_j << " ; ";
::std::cout << octonion_e_prime*octonion_k << " ; ";
::std::cout << octonion_e_prime*octonion_e_prime << " ; ";
::std::cout << octonion_e_prime*octonion_i_prime << " ; ";
::std::cout << octonion_e_prime*octonion_j_prime << " ; ";
::std::cout << octonion_e_prime*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_i_prime*octonion_1 << " ; ";
::std::cout << octonion_i_prime*octonion_i << " ; ";
::std::cout << octonion_i_prime*octonion_j << " ; ";
::std::cout << octonion_i_prime*octonion_k << " ; ";
::std::cout << octonion_i_prime*octonion_e_prime << " ; ";
::std::cout << octonion_i_prime*octonion_i_prime << " ; ";
::std::cout << octonion_i_prime*octonion_j_prime << " ; ";
::std::cout << octonion_i_prime*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_j_prime*octonion_1 << " ; ";
::std::cout << octonion_j_prime*octonion_i << " ; ";
::std::cout << octonion_j_prime*octonion_j << " ; ";
::std::cout << octonion_j_prime*octonion_k << " ; ";
::std::cout << octonion_j_prime*octonion_e_prime << " ; ";
::std::cout << octonion_j_prime*octonion_i_prime << " ; ";
::std::cout << octonion_j_prime*octonion_j_prime << " ; ";
::std::cout << octonion_j_prime*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << octonion_k_prime*octonion_1 << " ; ";
::std::cout << octonion_k_prime*octonion_i << " ; ";
::std::cout << octonion_k_prime*octonion_j << " ; ";
::std::cout << octonion_k_prime*octonion_k << " ; ";
::std::cout << octonion_k_prime*octonion_e_prime << " ; ";
::std::cout << octonion_k_prime*octonion_i_prime << " ; ";
::std::cout << octonion_k_prime*octonion_j_prime << " ; ";
::std::cout << octonion_k_prime*octonion_k_prime << " ; ";
::std::cout << ::std::endl;
::std::cout << ::std::endl;
::std::cout << "i\'*(e\'*j) : "
<< octonion_i_prime*(octonion_e_prime*octonion_j) << " ;" << ::std::endl;
::std::cout << "(i\'*e\')*j : "
<< (octonion_i_prime*octonion_e_prime)*octonion_j << " ;" << ::std::endl;
::std::cout << ::std::endl;
// tests for evaluation by scripts
using ::std::numeric_limits;
using ::boost::abs;
BOOST_CRITICAL_TEST(abs(::boost::octonion<float>(1,0,0,0,0,0,0,0)*
::boost::octonion<float>(1,0,0,0,0,0,0,0)-
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
for (int idx = 1; idx < 8; ++idx)
{
::boost::octonion<float>
toto(
(idx == 0) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 1) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 2) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 3) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 4) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 5) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 6) ?
static_cast<float>(1) :
static_cast<float>(0),
(idx == 7) ?
static_cast<float>(1) :
static_cast<float>(0)
);
BOOST_CRITICAL_TEST(abs(toto*toto+static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
}
BOOST_CRITICAL_TEST(abs(::boost::octonion<double>(1,0,0,0,0,0,0,0)*
::boost::octonion<double>(1,0,0,0,0,0,0,0)-
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
for (int idx = 1; idx < 8; ++idx)
{
::boost::octonion<double>
toto(
(idx == 0) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 1) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 2) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 3) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 4) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 5) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 6) ?
static_cast<double>(1) :
static_cast<double>(0),
(idx == 7) ?
static_cast<double>(1) :
static_cast<double>(0)
);
BOOST_CRITICAL_TEST(abs(toto*toto+static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
}
BOOST_CRITICAL_TEST(abs(::boost::octonion<long double>(1,0,0,0,0,0,0,0)*
::boost::octonion<long double>(1,0,0,0,0,0,0,0)-
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
for (int idx = 1; idx < 8; ++idx)
{
::boost::octonion<long double>
toto(
(idx == 0) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 1) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 2) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 3) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 4) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 5) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 6) ?
static_cast<long double>(1) :
static_cast<long double>(0),
(idx == 7) ?
static_cast<long double>(1) :
static_cast<long double>(0)
);
BOOST_CRITICAL_TEST(abs(toto*toto+static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
}
return(::boost::exit_success);
}

BIN
octonion/output.txt Normal file

Binary file not shown.

497
quaternion/HSO3.hpp Normal file
View File

@@ -0,0 +1,497 @@
/********************************************************************************************/
/* */
/* HSO3.hpp header file */
/* */
/* This file is not currently part of the Boost library. It is simply an example of the use */
/* quaternions can be put to. Hopefully it will be usefull too. */
/* */
/* This file provides tools to convert between quaternions and R^3 rotation matrices. */
/* */
/********************************************************************************************/
// (C) Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#ifndef TEST_HSO3_HPP
#define TEST_HSO3_HPP
#include <algorithm>
#include <limits>
#include <stdexcept>
#include <string>
#include <boost/math/quaternion.hpp>
template<typename TYPE_FLOAT>
struct R3_matrix
{
TYPE_FLOAT a11, a12, a13;
TYPE_FLOAT a21, a22, a23;
TYPE_FLOAT a31, a32, a33;
};
// Note: the input quaternion need not be of norm 1 for the following function
template<typename TYPE_FLOAT>
R3_matrix<TYPE_FLOAT> quaternion_to_R3_rotation(::boost::quaternion<TYPE_FLOAT> const & q)
{
using ::std::numeric_limits;
TYPE_FLOAT a = q.R_component_1();
TYPE_FLOAT b = q.R_component_2();
TYPE_FLOAT c = q.R_component_3();
TYPE_FLOAT d = q.R_component_4();
TYPE_FLOAT aa = a*a;
TYPE_FLOAT ab = a*b;
TYPE_FLOAT ac = a*c;
TYPE_FLOAT ad = a*d;
TYPE_FLOAT bb = b*b;
TYPE_FLOAT bc = b*c;
TYPE_FLOAT bd = b*d;
TYPE_FLOAT cc = c*c;
TYPE_FLOAT cd = c*d;
TYPE_FLOAT dd = d*d;
TYPE_FLOAT norme_carre = aa+bb+cc+dd;
if (norme_carre <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Argument to quaternion_to_R3_rotation is too small!");
::std::underflow_error bad_argument(error_reporting);
throw(bad_argument);
}
R3_matrix<TYPE_FLOAT> out_matrix;
out_matrix.a11 = (aa+bb-cc-dd)/norme_carre;
out_matrix.a12 = 2*(-ad+bc)/norme_carre;
out_matrix.a13 = 2*(ac+bd)/norme_carre;
out_matrix.a21 = 2*(ad+bc)/norme_carre;
out_matrix.a22 = (aa-bb+cc-dd)/norme_carre;
out_matrix.a23 = 2*(-ab+cd)/norme_carre;
out_matrix.a31 = 2*(-ac+bd)/norme_carre;
out_matrix.a32 = 2*(ab+cd)/norme_carre;
out_matrix.a33 = (aa-bb-cc+dd)/norme_carre;
return(out_matrix);
}
namespace
{
template<typename TYPE_FLOAT>
void find_invariant_vector(R3_matrix<TYPE_FLOAT> const & rot,
TYPE_FLOAT & x,
TYPE_FLOAT & y,
TYPE_FLOAT & z)
{
using ::std::sqrt;
using ::std::numeric_limits;
TYPE_FLOAT b11 = rot.a11 - static_cast<TYPE_FLOAT>(1);
TYPE_FLOAT b12 = rot.a12;
TYPE_FLOAT b13 = rot.a13;
TYPE_FLOAT b21 = rot.a21;
TYPE_FLOAT b22 = rot.a22 - static_cast<TYPE_FLOAT>(1);
TYPE_FLOAT b23 = rot.a23;
TYPE_FLOAT b31 = rot.a31;
TYPE_FLOAT b32 = rot.a32;
TYPE_FLOAT b33 = rot.a33 - static_cast<TYPE_FLOAT>(1);
TYPE_FLOAT minors[9] =
{
b11*b22-b12*b21,
b11*b23-b13*b21,
b12*b23-b13*b22,
b11*b32-b12*b31,
b11*b33-b13*b31,
b12*b33-b13*b32,
b21*b32-b22*b31,
b21*b33-b23*b31,
b22*b33-b23*b32
};
TYPE_FLOAT * where = ::std::max_element(minors, minors+9);
TYPE_FLOAT det = *where;
if (det <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Underflow error in find_invariant_vector!");
::std::underflow_error processing_error(error_reporting);
throw(processing_error);
}
switch (where-minors)
{
case 0:
z = static_cast<TYPE_FLOAT>(1);
x = (-b13*b22+b12*b23)/det;
y = (-b11*b23+b13*b21)/det;
break;
case 1:
y = static_cast<TYPE_FLOAT>(1);
x = (-b12*b23+b13*b22)/det;
z = (-b11*b22+b12*b21)/det;
break;
case 2:
x = static_cast<TYPE_FLOAT>(1);
y = (-b11*b23+b13*b21)/det;
z = (-b12*b21+b11*b22)/det;
break;
case 3:
z = static_cast<TYPE_FLOAT>(1);
x = (-b13*b32+b12*b33)/det;
y = (-b11*b33+b13*b31)/det;
break;
case 4:
y = static_cast<TYPE_FLOAT>(1);
x = (-b12*b33+b13*b32)/det;
z = (-b11*b32+b12*b31)/det;
break;
case 5:
x = static_cast<TYPE_FLOAT>(1);
y = (-b11*b33+b13*b31)/det;
z = (-b12*b31+b11*b32)/det;
break;
case 6:
z = static_cast<TYPE_FLOAT>(1);
x = (-b23*b32+b22*b33)/det;
y = (-b21*b33+b23*b31)/det;
break;
case 7:
y = static_cast<TYPE_FLOAT>(1);
x = (-b22*b33+b23*b32)/det;
z = (-b21*b32+b22*b31)/det;
break;
case 8:
x = static_cast<TYPE_FLOAT>(1);
y = (-b21*b33+b23*b31)/det;
z = (-b22*b31+b21*b32)/det;
break;
default:
::std::string error_reporting("Impossible condition in find_invariant_vector");
::std::logic_error processing_error(error_reporting);
throw(processing_error);
break;
}
TYPE_FLOAT vecnorm = sqrt(x*x+y*y+z*z);
if (vecnorm <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Overflow error in find_invariant_vector!");
::std::overflow_error processing_error(error_reporting);
throw(processing_error);
}
x /= vecnorm;
y /= vecnorm;
z /= vecnorm;
}
template<typename TYPE_FLOAT>
void find_orthogonal_vector(TYPE_FLOAT x,
TYPE_FLOAT y,
TYPE_FLOAT z,
TYPE_FLOAT & u,
TYPE_FLOAT & v,
TYPE_FLOAT & w)
{
using ::std::abs;
using ::std::sqrt;
using ::std::numeric_limits;
TYPE_FLOAT vecnormsqr = x*x+y*y+z*z;
if (vecnormsqr <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Underflow error in find_orthogonal_vector!");
::std::underflow_error processing_error(error_reporting);
throw(processing_error);
}
TYPE_FLOAT lambda;
TYPE_FLOAT components[3] =
{
abs(x),
abs(y),
abs(z)
};
TYPE_FLOAT * where = ::std::min_element(components, components+3);
switch (where-components)
{
case 0:
if (*where <= numeric_limits<TYPE_FLOAT>::epsilon())
{
v =
w = static_cast<TYPE_FLOAT>(0);
u = static_cast<TYPE_FLOAT>(1);
}
else
{
lambda = -x/vecnormsqr;
u = static_cast<TYPE_FLOAT>(1) + lambda*x;
v = lambda*y;
w = lambda*z;
}
break;
case 1:
if (*where <= numeric_limits<TYPE_FLOAT>::epsilon())
{
u =
w = static_cast<TYPE_FLOAT>(0);
v = static_cast<TYPE_FLOAT>(1);
}
else
{
lambda = -y/vecnormsqr;
u = lambda*x;
v = static_cast<TYPE_FLOAT>(1) + lambda*y;
w = lambda*z;
}
break;
case 2:
if (*where <= numeric_limits<TYPE_FLOAT>::epsilon())
{
u =
v = static_cast<TYPE_FLOAT>(0);
w = static_cast<TYPE_FLOAT>(1);
}
else
{
lambda = -z/vecnormsqr;
u = lambda*x;
v = lambda*y;
w = static_cast<TYPE_FLOAT>(1) + lambda*z;
}
break;
default:
::std::string error_reporting("Impossible condition in find_invariant_vector");
::std::logic_error processing_error(error_reporting);
throw(processing_error);
break;
}
TYPE_FLOAT vecnorm = sqrt(u*u+v*v+w*w);
if (vecnorm <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Underflow error in find_orthogonal_vector!");
::std::underflow_error processing_error(error_reporting);
throw(processing_error);
}
u /= vecnorm;
v /= vecnorm;
w /= vecnorm;
}
// Note: we want [[v, v, w], [r, s, t], [x, y, z]] to be a direct orthogonal basis
// of R^3. It might not be orthonormal, however, and we do not check if the
// two input vectors are colinear or not.
template<typename TYPE_FLOAT>
void find_vector_for_BOD(TYPE_FLOAT x,
TYPE_FLOAT y,
TYPE_FLOAT z,
TYPE_FLOAT u,
TYPE_FLOAT v,
TYPE_FLOAT w,
TYPE_FLOAT & r,
TYPE_FLOAT & s,
TYPE_FLOAT & t)
{
r = +y*w-z*v;
s = -x*w+z*u;
t = +x*v-y*u;
}
}
template<typename TYPE_FLOAT>
inline bool is_R3_rotation_matrix(R3_matrix<TYPE_FLOAT> const & mat)
{
using ::std::abs;
using ::std::numeric_limits;
return (
!(
(abs(mat.a11*mat.a11+mat.a21*mat.a21+mat.a31*mat.a31 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a12*mat.a12+mat.a22*mat.a22+mat.a32*mat.a32 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a13*mat.a13+mat.a23*mat.a23+mat.a33*mat.a33 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())
)
);
}
template<typename TYPE_FLOAT>
::boost::quaternion<TYPE_FLOAT> R3_rotation_to_quaternion(R3_matrix<TYPE_FLOAT> const & rot,
::boost::quaternion<TYPE_FLOAT> const * hint = 0)
{
using ::std::abs;
using ::std::sqrt;
using ::std::numeric_limits;
using ::boost::abs;
if (!is_R3_rotation_matrix(rot))
{
::std::string error_reporting("Argument to R3_rotation_to_quaternion is not an R^3 rotation matrix!");
::std::range_error bad_argument(error_reporting);
throw(bad_argument);
}
::boost::quaternion<TYPE_FLOAT> q;
if (
(abs(rot.a11 - static_cast<TYPE_FLOAT>(1)) <= numeric_limits<TYPE_FLOAT>::epsilon())&&
(abs(rot.a22 - static_cast<TYPE_FLOAT>(1)) <= numeric_limits<TYPE_FLOAT>::epsilon())&&
(abs(rot.a33 - static_cast<TYPE_FLOAT>(1)) <= numeric_limits<TYPE_FLOAT>::epsilon())
)
{
q = ::boost::quaternion<TYPE_FLOAT>(1);
}
else
{
TYPE_FLOAT cos_theta = (rot.a11+rot.a22+rot.a33-static_cast<TYPE_FLOAT>(1))/static_cast<TYPE_FLOAT>(2);
TYPE_FLOAT stuff = (cos_theta+static_cast<TYPE_FLOAT>(1))/static_cast<TYPE_FLOAT>(2);
TYPE_FLOAT cos_theta_sur_2 = sqrt(stuff);
TYPE_FLOAT sin_theta_sur_2 = sqrt(1-stuff);
TYPE_FLOAT x;
TYPE_FLOAT y;
TYPE_FLOAT z;
find_invariant_vector(rot, x, y, z);
TYPE_FLOAT u;
TYPE_FLOAT v;
TYPE_FLOAT w;
find_orthogonal_vector(x, y, z, u, v, w);
TYPE_FLOAT r;
TYPE_FLOAT s;
TYPE_FLOAT t;
find_vector_for_BOD(x, y, z, u, v, w, r, s, t);
TYPE_FLOAT ru = rot.a11*u+rot.a12*v+rot.a13*w;
TYPE_FLOAT rv = rot.a21*u+rot.a22*v+rot.a23*w;
TYPE_FLOAT rw = rot.a31*u+rot.a32*v+rot.a33*w;
TYPE_FLOAT angle_sign_determinator = r*ru+s*rv+t*rw;
if (angle_sign_determinator > +numeric_limits<TYPE_FLOAT>::epsilon())
{
q = ::boost::quaternion<TYPE_FLOAT>(cos_theta_sur_2, +x*sin_theta_sur_2, +y*sin_theta_sur_2, +z*sin_theta_sur_2);
}
else if (angle_sign_determinator < -numeric_limits<TYPE_FLOAT>::epsilon())
{
q = ::boost::quaternion<TYPE_FLOAT>(cos_theta_sur_2, -x*sin_theta_sur_2, -y*sin_theta_sur_2, -z*sin_theta_sur_2);
}
else
{
TYPE_FLOAT desambiguator = u*ru+v*rv+w*rw;
if (desambiguator >= static_cast<TYPE_FLOAT>(1))
{
q = ::boost::quaternion<TYPE_FLOAT>(0, +x, +y, +z);
}
else
{
q = ::boost::quaternion<TYPE_FLOAT>(0, -x, -y, -z);
}
}
}
if ((hint != 0) && (abs(*hint+q) < abs(*hint-q)))
{
return(-q);
}
return(q);
}
#endif /* TEST_HSO3_HPP */

444
quaternion/HSO3SO4.cpp Normal file
View File

@@ -0,0 +1,444 @@
// test file for HSO3.hpp and HSO4.hpp
// (C) Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#include <iostream>
#include <boost/math/quaternion.hpp>
#include "HSO3.hpp"
#include "HSO4.hpp"
const int number_of_intervals = 5;
const float pi = ::std::atan(1.0f)*4;
void test_SO3();
void test_SO4();
int main()
{
test_SO3();
test_SO4();
::std::cout << "That's all folks!" << ::std::endl;
}
//
// Test of quaternion and R^3 rotation relationship
//
void test_SO3_spherical()
{
::std::cout << "Testing spherical:" << ::std::endl;
::std::cout << ::std::endl;
const float rho = 1.0f;
float theta;
float phi1;
float phi2;
for (int idxphi2 = 0; idxphi2 <= number_of_intervals; idxphi2++)
{
phi2 = (-pi/2)+(idxphi2*pi)/number_of_intervals;
for (int idxphi1 = 0; idxphi1 <= number_of_intervals; idxphi1++)
{
phi1 = (-pi/2)+(idxphi1*pi)/number_of_intervals;
for (int idxtheta = 0; idxtheta <= number_of_intervals; idxtheta++)
{
theta = -pi+(idxtheta*(2*pi))/number_of_intervals;
//::std::cout << "theta = " << theta << " ; ";
//::std::cout << "phi1 = " << phi1 << " ; ";
//::std::cout << "phi2 = " << phi2;
//::std::cout << ::std::endl;
::boost::quaternion<float> q = ::boost::spherical(rho, theta, phi1, phi2);
//::std::cout << "q = " << q << ::std::endl;
R3_matrix<float> rot = quaternion_to_R3_rotation(q);
//::std::cout << "rot = ";
//::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
::boost::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
//::std::cout << "p = " << p << ::std::endl;
//::std::cout << "round trip discrepancy: " << ::boost::abs(q-p) << ::std::endl;
//::std::cout << ::std::endl;
}
}
}
::std::cout << ::std::endl;
}
void test_SO3_semipolar()
{
::std::cout << "Testing semipolar:" << ::std::endl;
::std::cout << ::std::endl;
const float rho = 1.0f;
float alpha;
float theta1;
float theta2;
for (int idxalpha = 0; idxalpha <= number_of_intervals; idxalpha++)
{
alpha = (idxalpha*(pi/2))/number_of_intervals;
for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
{
theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
{
theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
//::std::cout << "alpha = " << alpha << " ; ";
//::std::cout << "theta1 = " << theta1 << " ; ";
//::std::cout << "theta2 = " << theta2;
//::std::cout << ::std::endl;
::boost::quaternion<float> q = ::boost::semipolar(rho, alpha, theta1, theta2);
//::std::cout << "q = " << q << ::std::endl;
R3_matrix<float> rot = quaternion_to_R3_rotation(q);
//::std::cout << "rot = ";
//::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
::boost::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
//::std::cout << "p = " << p << ::std::endl;
//::std::cout << "round trip discrepancy: " << ::boost::abs(q-p) << ::std::endl;
//::std::cout << ::std::endl;
}
}
}
::std::cout << ::std::endl;
}
void test_SO3_multipolar()
{
::std::cout << "Testing multipolar:" << ::std::endl;
::std::cout << ::std::endl;
float rho1;
float rho2;
float theta1;
float theta2;
for (int idxrho = 0; idxrho <= number_of_intervals; idxrho++)
{
rho1 = (idxrho*1.0f)/number_of_intervals;
rho2 = ::std::sqrt(1.0f-rho1*rho1);
for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
{
theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
{
theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
//::std::cout << "rho1 = " << rho1 << " ; ";
//::std::cout << "theta1 = " << theta1 << " ; ";
//::std::cout << "theta2 = " << theta2;
//::std::cout << ::std::endl;
::boost::quaternion<float> q = ::boost::multipolar(rho1, theta1, rho2, theta2);
//::std::cout << "q = " << q << ::std::endl;
R3_matrix<float> rot = quaternion_to_R3_rotation(q);
//::std::cout << "rot = ";
//::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
::boost::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
//::std::cout << "p = " << p << ::std::endl;
//::std::cout << "round trip discrepancy: " << ::boost::abs(q-p) << ::std::endl;
//::std::cout << ::std::endl;
}
}
}
::std::cout << ::std::endl;
}
void test_SO3_cylindrospherical()
{
::std::cout << "Testing cylindrospherical:" << ::std::endl;
::std::cout << ::std::endl;
float t;
float radius;
float longitude;
float latitude;
for (int idxt = 0; idxt <= number_of_intervals; idxt++)
{
t = -1.0f+(idxt*2.0f)/number_of_intervals;
radius = ::std::sqrt(1.0f-t*t);
for (int idxlatitude = 0; idxlatitude <= number_of_intervals; idxlatitude++)
{
latitude = (-pi/2)+(idxlatitude*pi)/number_of_intervals;
for (int idxlongitude = 0; idxlongitude <= number_of_intervals; idxlongitude++)
{
longitude = -pi+(idxlongitude*(2*pi))/number_of_intervals;
//::std::cout << "t = " << t << " ; ";
//::std::cout << "longitude = " << longitude;
//::std::cout << "latitude = " << latitude;
//::std::cout << ::std::endl;
::boost::quaternion<float> q = ::boost::cylindrospherical(t, radius, longitude, latitude);
//::std::cout << "q = " << q << ::std::endl;
R3_matrix<float> rot = quaternion_to_R3_rotation(q);
//::std::cout << "rot = ";
//::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
::boost::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
//::std::cout << "p = " << p << ::std::endl;
//::std::cout << "round trip discrepancy: " << ::boost::abs(q-p) << ::std::endl;
//::std::cout << ::std::endl;
}
}
}
::std::cout << ::std::endl;
}
void test_SO3_cylindrical()
{
::std::cout << "Testing cylindrical:" << ::std::endl;
::std::cout << ::std::endl;
float r;
float angle;
float h1;
float h2;
for (int idxh2 = 0; idxh2 <= number_of_intervals; idxh2++)
{
h2 = -1.0f+(idxh2*2.0f)/number_of_intervals;
for (int idxh1 = 0; idxh1 <= number_of_intervals; idxh1++)
{
h1 = ::std::sqrt(1.0f-h2*h2)*(-1.0f+(idxh2*2.0f)/number_of_intervals);
r = ::std::sqrt(1.0f-h1*h1-h2*h2);
for (int idxangle = 0; idxangle <= number_of_intervals; idxangle++)
{
angle = -pi+(idxangle*(2*pi))/number_of_intervals;
//::std::cout << "angle = " << angle << " ; ";
//::std::cout << "h1 = " << h1;
//::std::cout << "h2 = " << h2;
//::std::cout << ::std::endl;
::boost::quaternion<float> q = ::boost::cylindrical(r, angle, h1, h2);
//::std::cout << "q = " << q << ::std::endl;
R3_matrix<float> rot = quaternion_to_R3_rotation(q);
//::std::cout << "rot = ";
//::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
::boost::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
//::std::cout << "p = " << p << ::std::endl;
//::std::cout << "round trip discrepancy: " << ::boost::abs(q-p) << ::std::endl;
//::std::cout << ::std::endl;
}
}
}
::std::cout << ::std::endl;
}
void test_SO3()
{
::std::cout << "Testing SO3:" << ::std::endl;
::std::cout << ::std::endl;
test_SO3_spherical();
test_SO3_semipolar();
test_SO3_multipolar();
test_SO3_cylindrospherical();
test_SO3_cylindrical();
}
//
// Test of quaternion and R^4 rotation relationship
//
void test_SO4_spherical()
{
::std::cout << "Testing spherical:" << ::std::endl;
::std::cout << ::std::endl;
const float rho1 = 1.0f;
const float rho2 = 1.0f;
float theta1;
float phi11;
float phi21;
float theta2;
float phi12;
float phi22;
for (int idxphi21 = 0; idxphi21 <= number_of_intervals; idxphi21++)
{
phi21 = (-pi/2)+(idxphi21*pi)/number_of_intervals;
for (int idxphi22 = 0; idxphi22 <= number_of_intervals; idxphi22++)
{
phi22 = (-pi/2)+(idxphi22*pi)/number_of_intervals;
for (int idxphi11 = 0; idxphi11 <= number_of_intervals; idxphi11++)
{
phi11 = (-pi/2)+(idxphi11*pi)/number_of_intervals;
for (int idxphi12 = 0; idxphi12 <= number_of_intervals; idxphi12++)
{
phi12 = (-pi/2)+(idxphi12*pi)/number_of_intervals;
for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
{
theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
{
theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
//::std::cout << "theta1 = " << theta1 << " ; ";
//::std::cout << "phi11 = " << phi11 << " ; ";
//::std::cout << "phi21 = " << phi21;
//::std::cout << "theta2 = " << theta2 << " ; ";
//::std::cout << "phi12 = " << phi12 << " ; ";
//::std::cout << "phi22 = " << phi22;
//::std::cout << ::std::endl;
::boost::quaternion<float> p1 = ::boost::spherical(rho1, theta1, phi11, phi21);
//::std::cout << "p1 = " << p1 << ::std::endl;
::boost::quaternion<float> q1 = ::boost::spherical(rho2, theta2, phi12, phi22);
//::std::cout << "q1 = " << q1 << ::std::endl;
::std::pair< ::boost::quaternion<float> , ::boost::quaternion<float> > pq1 =
::std::make_pair(p1,q1);
R4_matrix<float> rot = quaternions_to_R4_rotation(pq1);
//::std::cout << "rot = ";
//::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << "\t" << rot.a14 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << "\t" << rot.a24 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << "\t" << rot.a34 << ::std::endl;
//::std::cout << "\t";
//::std::cout << "\t" << rot.a41 << "\t" << rot.a42 << "\t" << rot.a43 << "\t" << rot.a44 << ::std::endl;
::std::pair< ::boost::quaternion<float> , ::boost::quaternion<float> > pq2 =
R4_rotation_to_quaternions(rot, &pq1);
//::std::cout << "p1 = " << pq.first << ::std::endl;
//::std::cout << "p2 = " << pq.second << ::std::endl;
//::std::cout << "round trip discrepancy: " << ::std::sqrt(::boost::norm(pq1.first-pq2.first)+::boost::norm(pq1.second-pq2.second)) << ::std::endl;
//::std::cout << ::std::endl;
}
}
}
}
}
}
::std::cout << ::std::endl;
}
void test_SO4()
{
::std::cout << "Testing SO4:" << ::std::endl;
::std::cout << ::std::endl;
test_SO4_spherical();
}

182
quaternion/HSO4.hpp Normal file
View File

@@ -0,0 +1,182 @@
/********************************************************************************************/
/* */
/* HSO4.hpp header file */
/* */
/* This file is not currently part of the Boost library. It is simply an example of the use */
/* quaternions can be put to. Hopefully it will be usefull too. */
/* */
/* This file provides tools to convert between quaternions and R^4 rotation matrices. */
/* */
/********************************************************************************************/
// (C) Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#ifndef TEST_HSO4_HPP
#define TEST_HSO4_HPP
#include <utility>
#include "HSO3.hpp"
template<typename TYPE_FLOAT>
struct R4_matrix
{
TYPE_FLOAT a11, a12, a13, a14;
TYPE_FLOAT a21, a22, a23, a24;
TYPE_FLOAT a31, a32, a33, a34;
TYPE_FLOAT a41, a42, a43, a44;
};
// Note: the input quaternions need not be of norm 1 for the following function
template<typename TYPE_FLOAT>
R4_matrix<TYPE_FLOAT> quaternions_to_R4_rotation(::std::pair< ::boost::quaternion<TYPE_FLOAT> , ::boost::quaternion<TYPE_FLOAT> > const & pq)
{
using ::std::numeric_limits;
TYPE_FLOAT a0 = pq.first.R_component_1();
TYPE_FLOAT b0 = pq.first.R_component_2();
TYPE_FLOAT c0 = pq.first.R_component_3();
TYPE_FLOAT d0 = pq.first.R_component_4();
TYPE_FLOAT norme_carre0 = a0*a0+b0*b0+c0*c0+d0*d0;
if (norme_carre0 <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Argument to quaternions_to_R4_rotation is too small!");
::std::underflow_error bad_argument(error_reporting);
throw(bad_argument);
}
TYPE_FLOAT a1 = pq.second.R_component_1();
TYPE_FLOAT b1 = pq.second.R_component_2();
TYPE_FLOAT c1 = pq.second.R_component_3();
TYPE_FLOAT d1 = pq.second.R_component_4();
TYPE_FLOAT norme_carre1 = a1*a1+b1*b1+c1*c1+d1*d1;
if (norme_carre1 <= numeric_limits<TYPE_FLOAT>::epsilon())
{
::std::string error_reporting("Argument to quaternions_to_R4_rotation is too small!");
::std::underflow_error bad_argument(error_reporting);
throw(bad_argument);
}
TYPE_FLOAT prod_norm = norme_carre0*norme_carre1;
TYPE_FLOAT a0a1 = a0*a1;
TYPE_FLOAT a0b1 = a0*b1;
TYPE_FLOAT a0c1 = a0*c1;
TYPE_FLOAT a0d1 = a0*d1;
TYPE_FLOAT b0a1 = b0*a1;
TYPE_FLOAT b0b1 = b0*b1;
TYPE_FLOAT b0c1 = b0*c1;
TYPE_FLOAT b0d1 = b0*d1;
TYPE_FLOAT c0a1 = c0*a1;
TYPE_FLOAT c0b1 = c0*b1;
TYPE_FLOAT c0c1 = c0*c1;
TYPE_FLOAT c0d1 = c0*d1;
TYPE_FLOAT d0a1 = d0*a1;
TYPE_FLOAT d0b1 = d0*b1;
TYPE_FLOAT d0c1 = d0*c1;
TYPE_FLOAT d0d1 = d0*d1;
R4_matrix<TYPE_FLOAT> out_matrix;
out_matrix.a11 = (+a0a1+b0b1+c0c1+d0d1)/prod_norm;
out_matrix.a12 = (+a0b1-b0a1-c0d1+d0c1)/prod_norm;
out_matrix.a13 = (+a0c1+b0d1-c0a1-d0b1)/prod_norm;
out_matrix.a14 = (+a0d1-b0c1+c0b1-d0a1)/prod_norm;
out_matrix.a21 = (-a0b1+b0a1-c0d1+d0c1)/prod_norm;
out_matrix.a22 = (+a0a1+b0b1-c0c1-d0d1)/prod_norm;
out_matrix.a23 = (-a0d1+b0c1+c0b1-d0a1)/prod_norm;
out_matrix.a24 = (+a0c1+b0d1+c0a1+d0b1)/prod_norm;
out_matrix.a31 = (-a0c1+b0d1+c0a1-d0b1)/prod_norm;
out_matrix.a32 = (+a0d1+b0c1+c0b1+d0a1)/prod_norm;
out_matrix.a33 = (+a0a1-b0b1+c0c1-d0d1)/prod_norm;
out_matrix.a34 = (-a0b1-b0a1+c0d1+d0c1)/prod_norm;
out_matrix.a41 = (-a0d1-b0c1+c0b1+d0a1)/prod_norm;
out_matrix.a42 = (-a0c1+b0d1-c0a1+d0b1)/prod_norm;
out_matrix.a43 = (+a0b1+b0a1+c0d1+d0c1)/prod_norm;
out_matrix.a44 = (+a0a1-b0b1-c0c1+d0d1)/prod_norm;
return(out_matrix);
}
template<typename TYPE_FLOAT>
inline bool is_R4_rotation_matrix(R4_matrix<TYPE_FLOAT> const & mat)
{
using ::std::abs;
using ::std::numeric_limits;
return (
!(
(abs(mat.a11*mat.a11+mat.a21*mat.a21+mat.a31*mat.a31+mat.a41*mat.a41 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32+mat.a41*mat.a42 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33+mat.a41*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a11*mat.a14+mat.a21*mat.a24+mat.a31*mat.a34+mat.a41*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32+mat.a41*mat.a42 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a12*mat.a12+mat.a22*mat.a22+mat.a32*mat.a32+mat.a42*mat.a42 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33+mat.a42*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a12*mat.a14+mat.a22*mat.a24+mat.a32*mat.a34+mat.a42*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33+mat.a41*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33+mat.a42*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a13*mat.a13+mat.a23*mat.a23+mat.a33*mat.a33+mat.a43*mat.a43 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a13*mat.a14+mat.a23*mat.a24+mat.a33*mat.a34+mat.a43*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a11*mat.a14+mat.a21*mat.a24+mat.a31*mat.a34+mat.a41*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a12*mat.a14+mat.a22*mat.a24+mat.a32*mat.a34+mat.a42*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
//(abs(mat.a13*mat.a14+mat.a23*mat.a24+mat.a33*mat.a34+mat.a43*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
(abs(mat.a14*mat.a14+mat.a24*mat.a24+mat.a34*mat.a34+mat.a44*mat.a44 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())
)
);
}
template<typename TYPE_FLOAT>
::std::pair< ::boost::quaternion<TYPE_FLOAT> , ::boost::quaternion<TYPE_FLOAT> > R4_rotation_to_quaternions(R4_matrix<TYPE_FLOAT> const & rot,
::std::pair< ::boost::quaternion<TYPE_FLOAT> , ::boost::quaternion<TYPE_FLOAT> > const * hint = 0)
{
if (!is_R4_rotation_matrix(rot))
{
::std::string error_reporting("Argument to R4_rotation_to_quaternions is not an R^4 rotation matrix!");
::std::range_error bad_argument(error_reporting);
throw(bad_argument);
}
R3_matrix<TYPE_FLOAT> mat;
mat.a11 = -rot.a31*rot.a42+rot.a32*rot.a41+rot.a22*rot.a11-rot.a21*rot.a12;
mat.a12 = -rot.a31*rot.a43+rot.a33*rot.a41+rot.a23*rot.a11-rot.a21*rot.a13;
mat.a13 = -rot.a31*rot.a44+rot.a34*rot.a41+rot.a24*rot.a11-rot.a21*rot.a14;
mat.a21 = -rot.a31*rot.a12-rot.a22*rot.a41+rot.a32*rot.a11+rot.a21*rot.a42;
mat.a22 = -rot.a31*rot.a13-rot.a23*rot.a41+rot.a33*rot.a11+rot.a21*rot.a43;
mat.a23 = -rot.a31*rot.a14-rot.a24*rot.a41+rot.a34*rot.a11+rot.a21*rot.a44;
mat.a31 = +rot.a31*rot.a22-rot.a12*rot.a41+rot.a42*rot.a11-rot.a21*rot.a32;
mat.a32 = +rot.a31*rot.a23-rot.a13*rot.a41+rot.a43*rot.a11-rot.a21*rot.a33;
mat.a33 = +rot.a31*rot.a24-rot.a14*rot.a41+rot.a44*rot.a11-rot.a21*rot.a34;
::boost::quaternion<TYPE_FLOAT> q = R3_rotation_to_quaternion(mat);
::boost::quaternion<TYPE_FLOAT> p =
::boost::quaternion<TYPE_FLOAT>(rot.a11,rot.a12,rot.a13,rot.a14)*q;
if ((hint != 0) && (abs(hint->second+q) < abs(hint->second-q)))
{
return(::std::make_pair(-p,-q));
}
return(::std::make_pair(p,q));
}
#endif /* TEST_HSO4_HPP */

2254
quaternion/TQE.pdf Normal file

File diff suppressed because one or more lines are too long

BIN
quaternion/TQE_EA.pdf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

70
quaternion/index.htm Normal file
View File

@@ -0,0 +1,70 @@
<html>
<head>
<title>Boost class quaternion</title>
<meta http-equiv="generator" content="Adobe GoLive 5">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2">
<tr>
<td bgcolor="#FFFFFF"><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" WIDTH="277" HEIGHT="86"></td>
<td><a href="../../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td>
<td><a href="../../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td>
<td><a href="../../../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td>
<td><a href="../../../more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td>
<td><a href="../../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td>
</tr>
</table>
<h2>The quaternion Class</h2>
<p>Class quaternion provides an implementation of the mathematical object of the same name.&nbsp; See the documentation for details. <ul>
<li><a href="quaternion.html">Documentation</a></li>
<li>Header <a href="../../../boost/math/quaternion.hpp">quaternion.hpp</a></li>
<li>Test program <a href="quaternion_test.cpp">quaternion_test.cpp</a></li>
<li>Download <a href="../../../more/download.html"> all of Boost</a>.</li>
<li>Submitted by Hubert Holin.</li>
</ul>
<h3>Comments</h3>
<p>Compiles and runs under MetroWerk's CodeWarrior Pro 6.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %b %Y" startspan -->07 June 2001<!--webbot bot="Timestamp" endspan i-checksum="15233" -->
</p>
</body>
</html>

BIN
quaternion/output.txt Normal file

Binary file not shown.

606
quaternion/quaternion.html Normal file
View File

@@ -0,0 +1,606 @@
<html>
<head>
<title>Class quaternion Documentation</title>
<meta http-equiv="generator" content="Adobe GoLive 5">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Class quaternion</h1>
<ul>
<li><a href="#Acknowledgements">Acknowledgements</a>
<li><a href="#Header File">Header File</a>
<li><a href="#Test Program">Test Program</a>
<li><a href="#Synopsis">Synopsis</a>
<li><a href="#Template class quaternion">Template class <code>quaternion</code></a>
<li><a href="#quaternion specializations"><code>quaternion</code> specializations</a>
<li><a href="#quaternion typedefs"><code>quaternion</code> typedefs</a>
<li><a href="#quaternion member functions"><code>quaternion</code> member functions</a>
<li><a href="#quaternion member operators"><code>quaternion</code> member operators</a>
<li><a href="#quaternion non-member operations"><code>quaternion</code> non-member operations</a>
<li><a href="#Other member functions"><code>quaternion</code> value operations</a>
<li><a href="#quaternion transcendentals"><code>quaternion</code> transcendentals</a>
<li><a href="#History">History</a>
</ul>
<p></p>
<p>Quaternions are a relative of complex numbers.</p>
<p>Quaternions are in fact part of a small hierarchy of structures built upon the real numbers, which comprise only the set of real numbers (traditionally named <img src="graphics/quaternion_blurb.html1.jpeg" width="12" height="11" naturalsizeflag="3" align=absmiddle>), the set of complex numbers (traditionally named <img src="graphics/quaternion_blurb.html2.jpeg" width="11" height="12" naturalsizeflag="3" align=absmiddle><font color="#000000">), the set of quaternions (traditionally named <img src="graphics/quaternion_blurb.html3.jpeg" width="12" height="11" naturalsizeflag="3" align=absmiddle>) and the set of <a href="../octonion/octonion.html">octonions</a> (traditionally named <img src="graphics/quaternion_blurb.html4.jpeg" width="12" height="12" naturalsizeflag="3" align=absmiddle>), which possess interesting mathematical properties (chief among which is the fact that they are <cite>division algebras</cite>, <cite>i.e.</cite> where the following property is true: if <img src="graphics/quaternion_blurb.html5.jpeg" width="9" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> is an element of that algebra and is <strong>not equal to zero</strong>, then <img src="graphics/quaternion_blurb.html6.jpeg" width="46" height="14" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, where <img src="graphics/quaternion_blurb.html7.jpeg" width="9" height="9" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> and <img src="graphics/quaternion_blurb.html8.jpeg" width="13" height="12" naturalsizeflag="3" align=absmiddle> denote elements of that algebra, implies that <img src="graphics/quaternion_blurb.html9.jpeg" width="32" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000">). Each member of the hierarchy is a super-set of the former.</font></p>
<p><font color="#000000">One of the most important aspects of quaternions is that they provide an efficient way to parameterize rotations in <img src="graphics/quaternion_blurb.html10.jpeg" width="15" height="13" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> (the usual three-dimensional space) and <img src="graphics/quaternion_blurb.html11.jpeg" width="16" height="13" naturalsizeflag="3" align=absmiddle></font><font color="#000000">.</font></p>
<p><font color="#000000">In practical terms, a quaternion is simply a quadruple of real numbers <img src="graphics/quaternion_blurb.html12.jpeg" width="52" height="16" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, which we can write in the form <img src="graphics/quaternion_blurb.html13.jpeg" width="104" height="14" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, where <img src="graphics/quaternion_blurb.html14.jpeg" width="6" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> is the same object as for complex numbers, and <img src="graphics/quaternion_blurb.html15.jpeg" width="8" height="13" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> and <img src="graphics/quaternion_blurb.html16.jpeg" width="9" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> are distinct objects which play essentially the same kind of role as <img src="graphics/quaternion_blurb.html17.jpeg" width="6" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000">.</font></p>
<p><font color="#000000">An addition and a multiplication is defined on the set of quaternions, which generalize their real and complex counterparts. The main novelty here is that <strong>the multiplication is not commutative</strong> (<cite>i.e.</cite> there are quaternions <img src="graphics/quaternion_blurb.html18.jpeg" width="9" height="9" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> and <img src="graphics/quaternion_blurb.html19.jpeg" width="9" height="11" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> such that <img src="graphics/quaternion_blurb.html20.jpeg" width="43" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000">). A good mnemotechnical way of remembering things is by using the formula <img src="graphics/quaternion_blurb.html21.jpeg" width="111" height="14" naturalsizeflag="3" align=absmiddle></font><font color="#000000">.</font></p>
<p><font color="#000000">Quaternions (and their kin) are described in far more details in this other <a href="TQE.pdf">document</a> (with <a href="TQE_EA.pdf">errata and addenda</a>).</font></p>
<p><font color="#000000">Some traditional constructs, such as the exponential, carry over without too much change into the realms of quaternions, but other, such as taking a square root, do not (the fact that the exponential has a closed form is a result of the author, but the fact that the exponential exists at all for quaternions is known since quite a long time ago).</font></p>
<h2><a name="Acknowledgements"></a>Acknowledgements</h2>
<p>The mathematical text has been typeset with <a href="http://www.nisus-soft.com/">Nisus Writer</a>. Jens Maurer has helped with portability and standard adherence, and was the Review Manager for this library. More acknowledgements in the History section. Thank you to all who contributed to the discution about this library.</p>
<h2><a name="Header File"></a>Header File</h2>
<p>The interface and implementation are both supplied by the header file <a href="../../boost/quaternion.hpp">quaternion.h</a>.</p>
<h2><a name="Test Program"></a>Test Program</h2>
<p>The <a href="quaternion_test.cpp">quaternion_test.cpp</a> test program tests quaternions specializations for float, double and long double (<a href="output.txt">sample output</a>).</p>
<p>It has been compiled and runs without error with the following C++ compilers:</p>
<blockquote>
<ul>
<li>MetroWerk's CodeWarrior Pro 6 on a Mac on a PowerPC G3
</ul>
</blockquote>
<h2><a name="Synopsis"></a>Synopsis</h2>
<pre><code>namespace boost
{
template&lt;typename T&gt; class <a href="#quaternion">quaternion</a>;
template&lt;&gt; class <a href="#quaternion<float>">quaternion&lt;float&gt;</a>;
template&lt;&gt; class <a href="#quaternion<double>">quaternion&lt;double&gt;</a>;
template&lt;&gt; class <a href="#quaternion<long double>">quaternion&lt;long double&gt;</a>;
// operators
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator +</a> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator +</a> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator +</a> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator +</a> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator +</a> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator -</a> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator -</a> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator -</a> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator -</a> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator -</a> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator *</a> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator *</a> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator *</a> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator *</a> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator *</a> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator /</a> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator /</a> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator /</a> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator /</a> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator /</a> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator +</a> (quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion non-member operations">operator -</a> (quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator ==</a> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator ==</a> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator ==</a> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator ==</a> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator ==</a> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator !=</a> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator !=</a> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator !=</a> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator !=</a> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <a href="#quaternion non-member operations">operator !=</a> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T, typename charT, class traits&gt;
::std::basic_istream&lt;charT,traits&gt; &amp; <a href="#quaternion non-member operations">operator &gt;&gt;</a> (::std::basic_istream&lt;charT,traits&gt; &amp; is, quaternion&lt;T&gt; &amp; q);
template&lt;typename T, typename charT, class traits&gt;
::std::basic_ostream&lt;charT,traits&gt; &amp; <a href="#quaternion non-member operations">operator &lt;&lt;</a> (::std::basic_ostream&lt;charT,traits&gt; &amp; os, quaternion&lt;T&gt; const &amp; q);
// values
template&lt;typename T&gt; inline T <a href="#quaternion value operations">real</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">unreal</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline T <a href="#quaternion value operations">sup</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline T <a href="#quaternion value operations">l1</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline T <a href="#quaternion value operations">abs</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline T <a href="#quaternion value operations">norm</a>(quaternion&lt;T&gt;const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">conj</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">spherical</a>(T const &amp; rho, T const &amp; theta, T const &amp; phi1, T const &amp; phi2);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">semipolar</a>(T const &amp; rho, T const &amp; alpha, T const &amp; theta1, T const &amp; theta2);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">multipolar</a>(T const &amp; rho1, T const &amp; theta1, T const &amp; rho2, T const &amp; theta2);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">cylindrospherical</a>(T const &amp; t, T const &amp; radius, T const &amp; longitude, T const &amp; latitude);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#quaternion value operations">cylindrical</a>(T const &amp; r, T const &amp; angle, T const &amp; h1, T const &amp; h2);
// transcendentals
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#exp">exp</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#cos">cos</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#sin">sin</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#tan">tan</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#cosh">cosh</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#sinh">sinh</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <a href="#tanh">tanh</a>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; quaternion&lt;T&gt; <a href="#pow">pow</a>(quaternion&lt;T&gt; const &amp; q, int n);
}</code></pre>
<h2><a name="Template class quaternion"></a>Template class <code>quaternion</code></h2>
<pre><code>namespace boost
{
<a name="quaternion"></a> template&lt;typename T&gt;
class quaternion
{
public:
typedef T <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">quaternion</a>(T const &amp; requested_a = T(), T const &amp; requested_b = T(), T const &amp; requested_c = T(), T const &amp; requested_d = T());
explicit <a href="#Constructors">quaternion</a>(::std::complex&lt;T&gt; const &amp; z0, ::std::complex&lt;T&gt; const &amp; z1 = ::std::complex&lt;T&gt;());
template&lt;typename X&gt; explicit <a href="#Constructors">quaternion</a>(quaternion&lt;X&gt; const &amp; a_recopier);
T <a href="#Other member functions">real</a>() const;
quaternion&lt;T&gt; <a href="#Other member functions">unreal</a>() const;
T <a href="#Other member functions">R_component_1</a>() const;
T <a href="#Other member functions">R_component_2</a>() const;
T <a href="#Other member functions">R_component_3</a>() const;
T <a href="#Other member functions">R_component_4</a>() const;
::std::complex&lt;T&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;T&gt; <a href="#Other member functions">C_component_2</a>() const;
quaternion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;T&gt; const &amp; a_affecter);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;X&gt; const &amp; a_affecter);
quaternion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (T const &amp; a_affecter);
quaternion&lt;T&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;T&gt; const &amp; a_affecter);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (T const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator +=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (T const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator -=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (T const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator *=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (T const &amp; rhs);
quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <a href="#Other member operators">operator /=</a> (quaternion&lt;X&gt; const &amp; rhs);
}
}</code></pre>
<p></p>
<h2><a name="quaternion specializations"></a><code>quaternion</code> specializations</h2>
<pre><code>namespace boost
{
<a name="quaternion<float>"></a> template&lt;&gt;
class quaternion&lt;float&gt;
{
public:
typedef float <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">quaternion</a>(float const &amp; requested_a = 0.0f, float const &amp; requested_b = 0.0f, float const &amp; requested_c = 0.0f, float const &amp; requested_d = 0.0f);
explicit <a href="#Constructors">quaternion</a>(::std::complex&lt;float&gt; const &amp; z0, ::std::complex&lt;float&gt; const &amp; z1 = ::std::complex&lt;float&gt;());
explicit <a href="#Constructors">quaternion</a>(quaternion&lt;double&gt; const &amp; a_recopier);
explicit <a href="#Constructors">quaternion</a>(quaternion&lt;long double&gt; const &amp; a_recopier);
float <a href="#Other member functions">real</a>() const;
quaternion&lt;float&gt; <a href="#Other member functions">unreal</a>() const;
float <a href="#Other member functions">R_component_1</a>() const;
float <a href="#Other member functions">R_component_2</a>() const;
float <a href="#Other member functions">R_component_3</a>() const;
float <a href="#Other member functions">R_component_4</a>() const;
::std::complex&lt;float&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;float&gt; <a href="#Other member functions">C_component_2</a>() const;
quaternion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;float&gt; const &amp; a_affecter);
template&lt;typename X&gt; quaternion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;X&gt;const &amp; a_affecter);
quaternion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (float const &amp; a_affecter);
quaternion&lt;float&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;float&gt; const &amp; a_affecter);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator +=</a> (float const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator +=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (float const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator -=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (float const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator *=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (float const &amp; rhs);
quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;float&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;float&gt; &amp; <a href="#Other member operators">operator /=</a> (quaternion&lt;X&gt; const &amp; rhs);
};
<a name="quaternion<double>"></a> template&lt;&gt;
class quaternion&lt;double&gt;
{
public:
typedef double <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">quaternion</a>(double const &amp; requested_a = 0.0, double const &amp; requested_b = 0.0, double const &amp; requested_c = 0.0, double const &amp; requested_d = 0.0);
explicit <a href="#Constructors">quaternion</a>(::std::complex&lt;double&gt; const &amp; z0, ::std::complex&lt;double&gt; const &amp; z1 = ::std::complex&lt;double&gt;());
explicit <a href="#Constructors">quaternion</a>(quaternion&lt;float&gt; const &amp; a_recopier);
explicit <a href="#Constructors">quaternion</a>(quaternion&lt;long double&gt; const &amp; a_recopier);
double <a href="#Other member functions">real</a>() const;
quaternion&lt;double&gt; <a href="#Other member functions">unreal</a>() const;
double <a href="#Other member functions">R_component_1</a>() const;
double <a href="#Other member functions">R_component_2</a>() const;
double <a href="#Other member functions">R_component_3</a>() const;
double <a href="#Other member functions">R_component_4</a>() const;
::std::complex&lt;double&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;double&gt; <a href="#Other member functions">C_component_2</a>() const;
quaternion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;double&gt; const &amp; a_affecter);
template&lt;typename X&gt; quaternion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;X&gt; const &amp; a_affecter);
quaternion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (double const &amp; a_affecter);
quaternion&lt;double&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;double&gt; const &amp; a_affecter);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (double const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator +=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (double const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator -=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (double const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator *=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (double const &amp; rhs);
quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;double&gt; &amp; <a href="#Other member operators">operator /=</a> (quaternion&lt;X&gt; const &amp; rhs);
};
<a name="quaternion<long double>"></a> template&lt;&gt;
class quaternion&lt;long double&gt;
{
public:
typedef long double <a href="#value_type">value_type</a>;
explicit <a href="#Constructors">quaternion</a>(long double const &amp; requested_a = 0.0L, long double const &amp; requested_b = 0.0L, long double const &amp; requested_c = 0.0L, long double const &amp; requested_d = 0.0L);
explicit <a href="#Constructors">quaternion</a>( ::std::complex&lt;long double&gt; const &amp; z0, ::std::complex&lt;long double&gt; const &amp; z1 = ::std::complex&lt;long double&gt;());
explicit <a href="#Constructors">quaternion</a>(quaternion&lt;float&gt; const &amp; a_recopier);
explicit <a href="#Constructors">quaternion</a>(quaternion&lt;double&gt; const &amp; a_recopier);
long double <a href="#Other member functions">real</a>() const;
quaternion&lt;long double&gt; <a href="#Other member functions">unreal</a>() const;
long double <a href="#Other member functions">R_component_1</a>() const;
long double <a href="#Other member functions">R_component_2</a>() const;
long double <a href="#Other member functions">R_component_3</a>() const;
long double <a href="#Other member functions">R_component_4</a>() const;
::std::complex&lt;long double&gt; <a href="#Other member functions">C_component_1</a>() const;
::std::complex&lt;long double&gt; <a href="#Other member functions">C_component_2</a>() const;
quaternion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;long double&gt; const &amp; a_affecter);
template&lt;typename X&gt; quaternion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (quaternion&lt;X&gt; const &amp; a_affecter);
quaternion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (long double const &amp; a_affecter);
quaternion&lt;long double&gt; &amp; <a href="#Assignment operators">operator =</a> (::std::complex&lt;long double&gt; const &amp; a_affecter);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (long double const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator +=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (long double const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator -=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (long double const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator *=</a> (quaternion&lt;X&gt; const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (long double const &amp; rhs);
quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (::std::complex&lt;long double&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;long double&gt; &amp; <a href="#Other member operators">operator /=</a> (quaternion&lt;X&gt; const &amp; rhs);
};
}</code></pre>
<p></p>
<h2><a name="quaternion typedefs"></a><code>quaternion</code> typedefs</h2>
<h3><a name="value_type"></a><code>value_type</code></h3>
<pre><code>typedef T <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Template version.</p>
</blockquote>
<pre><code>typedef float <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Float specialization version.</p>
</blockquote>
<pre><code>typedef double <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Double specialization version.</p>
</blockquote>
<pre><code>typedef long double <strong>value_type</strong>;</code></pre>
<blockquote>
<p>Long double specialization version.</p>
<p>These provide easy acces to the type the template is built upon.</p>
</blockquote>
<h2><a name="quaternion member functions"></a><code>quaternion</code> member functions</h2>
<h3><a name="Constructors"></a>Constructors</h3>
<pre><code>explicit <strong>quaternion</strong>(T const &amp; requested_a = T(), T const &amp; requested_b = T(), T const &amp; requested_c = T(), T const &amp; requested_d = T());
explicit <strong>quaternion</strong>(::std::complex&lt;T&gt; const &amp; z0, ::std::complex&lt;T&gt; const &amp; z1 = ::std::complex&lt;T&gt;());
template&lt;typename X&gt; explicit <strong>quaternion</strong>(quaternion&lt;X&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Template version.</p>
</blockquote>
<pre><code>explicit <strong>quaternion</strong>(float const &amp; requested_a = 0.0f, float const &amp; requested_b = 0.0f, float const &amp; requested_c = 0.0f, float const &amp; requested_d = 0.0f);
explicit <strong>quaternion</strong>(::std::complex&lt;float&gt; const &amp; z0,::std::complex&lt;float&gt; const &amp; z1 = ::std::complex&lt;float&gt;());
explicit <strong>quaternion</strong>(quaternion&lt;double&gt; const &amp; a_recopier);
explicit <strong>quaternion</strong>(quaternion&lt;long double&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Float specialization version.</p>
</blockquote>
<pre><code>explicit <strong>quaternion</strong>(double const &amp; requested_a = 0.0, double const &amp; requested_b = 0.0, double const &amp; requested_c = 0.0, double const &amp; requested_d = 0.0);
explicit <strong>quaternion</strong>(::std::complex&lt;double&gt; const &amp; z0, ::std::complex&lt;double&gt; const &amp; z1 = ::std::complex&lt;double&gt;());
explicit <strong>quaternion</strong>(quaternion&lt;float&gt; const &amp; a_recopier);
explicit <strong>quaternion</strong>(quaternion&lt;long double&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Double specialization version.</p>
</blockquote>
<pre><code>explicit <strong>quaternion</strong>(long double const &amp; requested_a = 0.0L, long double const &amp; requested_b = 0.0L, long double const &amp; requested_c = 0.0L, long double const &amp; requested_d = 0.0L);
explicit <strong>quaternion</strong>( ::std::complex&lt;long double&gt; const &amp; z0, ::std::complex&lt;long double&gt; const &amp; z1 = ::std::complex&lt;long double&gt;());
explicit <strong>quaternion</strong>(quaternion&lt;float&gt; const &amp; a_recopier);
explicit <strong>quaternion</strong>(quaternion&lt;double&gt; const &amp; a_recopier);</code></pre>
<blockquote>
<p>Long double specialization version.</p>
<p>A default constructor is provided for each form, which initializes each component to the default values for their type (<cite>i.e.</cite> zero for floating numbers). This constructor can also accept one to four base type arguments. A constructor is also provided to build quaternions from one or two complex numbers sharing the same base type. The unspecialized template also sports a templarized copy constructor, while the specialized forms have copy constructors from the other two specializations, which are explicit when a risk of precision loss exists. For the unspecialized form, the base type's constructors must not throw.</p>
<p>Destructors and untemplated copy constructors (from the same type) are provided by the compiler.</p>
</blockquote>
<h3><a name="Other member functions"></a>Other member functions</h3>
<pre><code>T <strong>real</strong>() const;
quaternion&lt;T&gt; <strong>unreal</strong>() const;</code></pre>
<blockquote>
<p>Like complex number, quaternions do have a meaningful notion of &quot;real part&quot;, but unlike them there is no meaningful notion of &quot;imaginary part&quot;. Instead there is an &quot;unreal part&quot; which itself is a quaternion, and usually nothing simpler (as opposed to the complex number case). These are returned by the first two functions.</p>
</blockquote>
<pre><code>T <strong>R_component_1</strong>() const;
T <strong>R_component_2</strong>() const;
T <strong>R_component_3</strong>() const;
T <strong>R_component_4</strong>() const;</code></pre>
<blockquote>
<p>A quaternion having four real components, these are returned by these four functions. Hence <code>real</code> and <code>R_component_1</code> return the same value.</p>
</blockquote>
<pre><code>::std::complex&lt;T&gt; <strong>C_component_1</strong>() const;
::std::complex&lt;T&gt; <strong>C_component_2</strong>() const;</code></pre>
<blockquote>
<p>A quaternion likewise has two complex components, and as we have seen above, <font color="#000000">for any quaternion <img src="graphics/quaternion_blurb.html22.jpeg" width="107" height="14" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> we also have <img src="graphics/quaternion_blurb.html23.jpeg" width="115" height="16" naturalsizeflag="3" align=absmiddle></font><font color="#000000">.</font> These functions return them. The real part of <code>q.C_component_1()</code> is the same as <code>q.real()</code>.</p>
</blockquote>
<h2><a name="quaternion member operators"></a><code>quaternion</code> member operators</h2>
<h3><a name="Assignment operators"></a>Assignment operators</h3>
<pre><code>quaternion&lt;T&gt; &amp; <strong>operator =</strong> (quaternion&lt;T&gt; const &amp; a_affecter);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <strong>operator =</strong> (quaternion&lt;X&gt; const &amp; a_affecter);
quaternion&lt;T&gt; &amp; <strong>operator =</strong> (T const &amp; a_affecter);
quaternion&lt;T&gt; &amp; <strong>operator =</strong> (::std::complex&lt;T&gt; const &amp; a_affecter);</code></pre>
<blockquote>
<p>These perform the expected assignment, with type modification if necessary (for instance, assigning from a base type will set the real part to that value, and all other components to zero). For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<h3><a name="Other member operators"></a>Other member operators</h3>
<pre><code>quaternion&lt;T&gt; &amp; <strong>operator +=</strong> (T const &amp; rhs)
quaternion&lt;T&gt; &amp; <strong>operator +=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <strong>operator +=</strong> (quaternion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)+rhs and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<pre><code>quaternion&lt;T&gt; &amp; <strong>operator -=</strong> (T const &amp; rhs)
quaternion&lt;T&gt; &amp; <strong>operator -=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <strong>operator -=</strong> (quaternion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)-rhs and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<pre><code>quaternion&lt;T&gt; &amp; <strong>operator *=</strong> (T const &amp; rhs)
quaternion&lt;T&gt; &amp; <strong>operator *=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <strong>operator *=</strong> (quaternion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)*rhs <strong>in this order</strong> (order is important as multiplication is not commutative for quaternions) and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<pre><code>quaternion&lt;T&gt; &amp; <strong>operator /=</strong> (T const &amp; rhs)
quaternion&lt;T&gt; &amp; <strong>operator /=</strong> (::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename X&gt; quaternion&lt;T&gt; &amp; <strong>operator /=</strong> (quaternion&lt;X&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These perform the mathematical operation (*this)*inverse_of(rhs) <strong>in this order</strong> (order is important as multiplication is not commutative for quaternions) and store the result in *this. The unspecialized form has exception guards, which the specialized forms do not, so as to insure exception safety. For the unspecialized form, the base type's assignment operators must not throw.</p>
</blockquote>
<h2><a name="quaternion non-member operations"></a><code>quaternion</code> non-member operations</h2>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator +</strong> (quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>This unary operator simply returns <code>q</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator -</strong> (quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>This unary operator returns the opposite of <code>q</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator +</strong> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator +</strong> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator +</strong> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator +</strong> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator +</strong> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>quaternion&lt;T&gt;(lhs) += rhs</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator -</strong> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator -</strong> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator -</strong> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator -</strong> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator -</strong> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>quaternion&lt;T&gt;(lhs) -= rhs</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator *</strong> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator *</strong> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator *</strong> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator *</strong> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator *</strong> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>quaternion&lt;T&gt;(lhs) *= rhs</code>.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator /</strong> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator /</strong> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator /</strong> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator /</strong> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>operator /</strong> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These operators return <code>quaternion&lt;T&gt;(lhs) /= rhs</code>. It is of course still an error to divide by zero...</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline bool <strong>operator ==</strong> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator ==</strong> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These return <code>true</code> if and only if the four components of <code>quaternion&lt;T&gt;(lhs)</code> are equal to their counterparts in <code>quaternion&lt;T&gt;(rhs)</code>. As with any floating-type entity, this is essentially meaningless.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline bool <strong>operator !=</strong> (T const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (quaternion&lt;T&gt; const &amp; lhs, T const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (::std::complex&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (quaternion&lt;T&gt; const &amp; lhs, ::std::complex&lt;T&gt; const &amp; rhs);
template&lt;typename T&gt; inline bool <strong>operator !=</strong> (quaternion&lt;T&gt; const &amp; lhs, quaternion&lt;T&gt; const &amp; rhs);</code></pre>
<blockquote>
<p>These return <code>true</code> if and only if <code>quaternion&lt;T&gt;(lhs) == quaternion&lt;T&gt;(rhs)</code> is <code>false</code>. As with any floating-type entity, this is essentially meaningless.</p>
</blockquote>
<pre><code>template&lt;typename T, typename charT, class traits&gt;
::std::basic_istream&lt;charT,traits&gt; &amp; <strong>operator &gt;&gt;</strong> (::std::basic_istream&lt;charT,traits&gt; &amp; is, quaternion&lt;T&gt; &amp; q);</code></pre>
<blockquote>
<p>Extracts a quaternion <code>q</code> of one of the following forms (with a, b, c and d of type <code>T</code>):</p>
<p>
a
(a), (a,b), (a,b,c), (a,b,c,d)
(a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b),(c,d))</p>
<p>The input values must be convertible to T. If bad input is encountered, calls is.setstate(ios::failbit) (which may throw ios::failure (27.4.5.3)).</p>
<p>Returns <code>is</code>.</p>
<p>The rationale for the list of accepted formats is that either we have a list of up to four reals, or else we have a couple of complex numbers, and in that case if it formated as a proper complex number, then it should be accepted. Thus potential ambiguities are lifted (for instance (a,b) is (a,b,0,0) and not (a,0,b,0), <cite>i.e.</cite> it is parsed as a list of two real numbers and not two complex numbers which happen to have imaginary parts equal to zero).</p>
</blockquote>
<pre><code>template&lt;typename T, typename charT, class traits&gt;
::std::basic_ostream&lt;charT,traits&gt; &amp; <strong>operator &lt;&lt;</strong> (::std::basic_ostream&lt;charT,traits&gt; &amp; os, quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Inserts the quaternion <code>q</code> onto the stream <code>os</code> as if it were implemented as follows (which it actually is):</p>
</blockquote>
<pre><code> template&lt;typename T, typename charT, class traits&gt;
::std::basic_ostream&lt;charT,traits&gt; &amp; operator &lt;&lt; ( ::std::basic_ostream&lt;charT,traits&gt; &amp; os,
quaternion&lt;T&gt; const &amp; q)
{
::std::basic_ostringstream&lt;charT,traits&gt; s;
s.flags(os.flags());
s.imbue(os.getloc());
s.precision(os.precision());
s &lt;&lt; '(' &lt;&lt; q.R_component_1() &lt;&lt; ','
&lt;&lt; q.R_component_2() &lt;&lt; ','
&lt;&lt; q.R_component_3() &lt;&lt; ','
&lt;&lt; q.R_component_4() &lt;&lt; ')' &lt;&lt; ::std::ends;
return os &lt;&lt; s.str();
}</code></pre>
<h2><a name="quaternion value operations"></a><code>quaternion</code> value operations</h2>
<pre><code>template&lt;typename T&gt; inline T <strong>real</strong>(quaternion&lt;T&gt; const &amp; q);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>unreal</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>These return <code>q.real()</code> and <code>q.unreal()</code> respectively.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>conj</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>This returns the conjugate of the quaternion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>sup</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>This return the sup norm (the greatest among <code>abs(q.R_component_1())</code>...<code>abs(q.R_component_4())</code>) of the quaternion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>l1</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>This return the l1 norm (<code>abs(q.R_component_1())+...+abs(q.R_component_4())</code>) of the quaternion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>abs</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>This return the magnitude (Euclidian norm) of the quaternion.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline T <strong>norm</strong>(quaternion&lt;T&gt;const &amp; q);</code></pre>
<blockquote>
<p>This return the (Cayley) norm of the quaternion. The term &quot;norm&quot; might be confusing, as most people associate it with the Euclidian norm (and quadratic functionals). For this version of (the mathematical objects known as) quaternions, the Euclidian norm (also known as magnitude) is the square root of the Cayley norm.</p>
</blockquote>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>spherical</strong>(T const &amp; rho, T const &amp; theta, T const &amp; phi1, T const &amp; phi2);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>semipolar</strong>(T const &amp; rho, T const &amp; alpha, T const &amp; theta1, T const &amp; theta2);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>multipolar</strong>(T const &amp; rho1, T const &amp; theta1, T const &amp; rho2, T const &amp; theta2);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>cylindrospherical</strong>(T const &amp; t, T const &amp; radius, T const &amp; longitude, T const &amp; latitude);
template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>cylindrical</strong>(T const &amp; r, T const &amp; angle, T const &amp; h1, T const &amp; h2);</code></pre>
<blockquote>
<p>These build quaternions in a way similar to the way <code>polar</code> builds complex numbers, as there is no strict equivalent to polar coordinates for quaternions.</p>
<p><code>spherical</code> is a simple transposition of <code>polar</code>, it takes as inputs a (positive) magnitude and a point on the hypersphere, given by three angles. The first of these, <code>theta</code> has a natural range of -pi to +pi, and the other two have natural ranges of -pi/2 to +pi/2 (as is the case with the usual spherical coordinates in R^3). Due to the many symmetries and periodicities, nothing untoward happens if the magnitude is negative or the angles are outside their natural ranges. The expected degeneracies (a magnitude of zero ignores the angles settings...) do happen however.</p>
<p><code>cylindrical</code> is likewise a simple transposition of the usual cylindrical coordinates in R^3, which in turn is another derivative of planar polar coordinates. The first two inputs are the polar coordinates of the first C component of the quaternion. The third and fourth inputs are placed into the third and fourth R components of the quaternion, respectively.</p>
<p><code>multipolar</code> is yet another simple generalization of polar coordinates. This time, both C components of the quaternion are given in polar coordinates.</p>
<p><code>cylindrospherical</code> is specific to quaternions. It is often interesting to consider H as the cartesian product of R by R^3 (the quaternionic multiplication as then a special form, as given here). This function therefore builds a quaternion from this representation, with the R^3 component given in usual R^3 spherical coordinates.</p>
<p><code>semipolar</code> is another generator which is specific to quaternions. It takes as a first input the magnitude of the quaternion, as a second input an angle in the range 0 to +pi/2 such that magnitudes of the first two C components of the quaternion are the product of the first input and the sine and cosine of this angle, respectively, and finally as third and fourth inputs angles in the range -pi/2 to +pi/2 which represent the arguments of the first and second C components of the quaternion, respectively. As usual, nothing untoward happens if what should be magnitudes are negative numbers or angles are out of their natural ranges, as symmetries and periodicities kick in.</p>
</blockquote>
<p>In this version of our implementation of quaternions, there is no analogue of the complex value operation <code>arg</code> as the situation is somewhat more complicated. Unit quaternions are linked both to rotations in R^3 and in R^4, and the correspondences are not too complicated, but there is currently a lack of standard (<cite>de facto</cite> or <cite>de jure</cite>) matrix library with which the conversions could work. This should be remedied in a further revision. In the mean time, an example of how this could be done is presented here <a href="HSO3.hpp">for R^3</a>, and here <a href="HSO4.hpp">for R^4</a> (<a href="HSO3SO4.cpp">example</a> test file).</p>
<h2><a name="quaternion transcendentals"></a><code>quaternion</code> transcendentals</h2>
<p>There is no <code>log</code> or <code>sqrt</code> provided for quaternions in this implementation, and <code>pow</code> is likewise restricted to integral powers of the exponent. There are several reasons to this: on the one hand, the equivalent of analytic continuation for quaternions (&quot;branch cuts&quot;) remains to be investigated thoroughly (by me, at any rate...), and we wish to avoid the nonsense introduced in the standard by exponentiations of complexes by complexes (which is well defined, but not in the standard...). Talking of nonsense, saying that <code>pow(0,0)</code> is &quot;implementation defined&quot; is just plain brain-dead...</p>
<p>We do, however provide several transcendentals, chief among which is the exponential. That it allows for a &quot;closed formula&quot; is a result of the author (the existence and definition of the exponential, on the quaternions among others, on the other hand, is a few centuries old). Basically, any converging power series with real coefficients which allows for a closed formula in C can be transposed to H. More transcendentals of this type could be added in a further revision upon request. It should be noted that it is these functions which force the dependency upon the <a href="../../../boost/math/special_functions/sinc.hpp">boost/math/<code>special_functions/sinc.hpp</code></a> and the <a href="../../../boost/math/special_functions/sinhc.hpp">boost/math/<code>special_functions/sinhc.hpp</code></a> headers.</p>
<h3><a name="exp"></a>exp</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>exp</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the exponential of the quaternion.</p>
</blockquote>
<h3><a name="cos"></a>cos</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>cos</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the cosine of the quaternion</p>
</blockquote>
<h3><a name="sin"></a>sin</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>sin</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the sine of the quaternion.</p>
</blockquote>
<h3><a name="tan"></a>tan</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>tan</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the tangent of the quaternion.</p>
</blockquote>
<h3><a name="cosh"></a>cosh</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>cosh</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the hyperbolic cosine of the quaternion.</p>
</blockquote>
<h3><a name="sinh"></a>sinh</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>sinh</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the hyperbolic sine of the quaternion.</p>
</blockquote>
<h3><a name="tanh"></a>tanh</h3>
<pre><code>template&lt;typename T&gt; inline quaternion&lt;T&gt; <strong>tanh</strong>(quaternion&lt;T&gt; const &amp; q);</code></pre>
<blockquote>
<p>Computes the hyperbolic tangent of the quaternion.</p>
</blockquote>
<h3><a name="pow"></a>pow</h3>
<pre><code>template&lt;typename T&gt; quaternion&lt;T&gt; <strong>pow</strong>(quaternion&lt;T&gt; const &amp; q, int n);</code></pre>
<blockquote>
<p>Computes the <code>n</code>-th power of the quaternion <code>q</code>.</p>
</blockquote>
<h2><a name="History"></a>History</h2>
<ul>
<li>1.5.1 - 07/06/2001: (end of Boost review) now includes <code>&lt;boost/math/special_functions/sinc.hpp&gt;</code> and <code>&lt;boost/math/special_functions/sinhc.hpp&gt;</code> instead of <code>&lt;boost/special_functions.hpp&gt;</code>; corrected bug in <code>sin</code> (Daryle Walker); removed check for self-assignment (Gary Powel); made converting functions <code>explicit</code> (Gary Powel); added overflow guards for division operators and <code>abs</code> (Peter Schmitteckert); added <code>sup</code> and <code>l1</code>; used Vesa Karvonen's CPP metaprograming technique to simplify code.
<li>1.5.0 - 26/03/2001: boostification, inlining of all operators except input, output and <code>pow</code>, fixed exception safety of some members (template version) and output operator, added <code>spherical</code>, <code>semipolar</code>, <code>multipolar</code>, <code>cylindrospherical</code> and <code>cylindrical</code>.
<li>1.4.0 - 09/01/2001: added <code>tan</code> and <code>tanh</code>. <li>1.3.1 - 08/01/2001: cosmetic fixes.
<li>1.3.0 - 12/07/2000: <code>pow</code> now uses Maarten Hilferink's (mhilferink@tip.nl) algorithm. <li>1.2.0 - 25/05/2000: fixed the division operators and output; changed many signatures.
<li>1.1.0 - 23/05/2000: changed <code>sinc</code> into <code>sinc_pi</code>; added <code>sin</code>, <code>cos</code>, <code>sinh</code>, <code>cosh</code>. <li>1.0.0 - 10/08/1999: first public version.
</ul>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 June 2001<!--webbot bot="Timestamp" endspan i-checksum="32118" --></p>
<p>&copy; Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This software is provided &quot;as is&quot; without express or implied&nbsp; warranty, and with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@@ -0,0 +1,809 @@
// test file for quaternion.hpp
// (C) Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#define BOOST_INTERACTIVE_TEST_INPUT_ITERATOR 0
#include <iostream>
#include <sstream>
#include <boost/math/quaternion.hpp>
// explicit (if ludicrous) instanciation
#ifndef __GNUC__
template class ::boost::quaternion<int>;
#else
// gcc doesn't like the absolutely-qualified namespace
template class boost::quaternion<int>;
#endif
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
#include <boost/test/test_tools.hpp>
int test_main(int, char *[])
{
// tests for evaluation by humans
// using default constructor
::boost::quaternion<float> q0;
::boost::quaternion<float> qa[2];
// using constructor "H seen as R^4"
::boost::quaternion<double> q1(1,2,3,4);
::std::complex<float> c0(5,6);
// using constructor "H seen as C^2"
::boost::quaternion<float> q2(c0);
// using UNtemplated copy constructor
::boost::quaternion<float> q3(q2);
// using templated copy constructor
::boost::quaternion<long double> q4(q3);
// using UNtemplated assignment operator
q3 = q0;
// using templated assignment operator
q4 = q0;
float f0(7);
// using converting assignment operator
q2 = f0;
// using converting assignment operator
q3 = c0;
// using += (const T &)
q2 += f0;
// using += (const ::std::complex<T> &)
q2 += c0;
// using += (const quaternion<X> &)
q2 += q3;
// using -= (const T &)
q3 -= f0;
// using -= (const ::std::complex<T> &)
q3 -= c0;
// using -= (const quaternion<X> &)
q3 -= q2;
double d0(8);
::std::complex<double> c1(9,10);
// using *= (const T &)
q1 *= d0;
// using *= (const ::std::complex<T> &)
q1 *= c1;
// using *= (const quaternion<X> &)
q1 *= q1;
long double l0(11);
::std::complex<long double> c2(12,13);
// using /= (const T &)
q4 /= l0;
// using /= (const ::std::complex<T> &)
q4 /= c2;
// using /= (const quaternion<X> &)
q4 /= q1;
// using + (const T &, const quaternion<T> &)
::boost::quaternion<float> q5 = f0+q2;
// using + (const quaternion<T> &, const T &)
::boost::quaternion<float> q6 = q2+f0;
// using + (const ::std::complex<T> &, const quaternion<T> &)
::boost::quaternion<float> q7 = c0+q2;
// using + (const quaternion<T> &, const ::std::complex<T> &)
::boost::quaternion<float> q8 = q2+c0;
// using + (const quaternion<T> &,const quaternion<T> &)
::boost::quaternion<float> q9 = q2+q3;
// using - (const T &, const quaternion<T> &)
q5 = f0-q2;
// using - (const quaternion<T> &, const T &)
q6 = q2-f0;
// using - (const ::std::complex<T> &, const quaternion<T> &)
q7 = c0-q2;
// using - (const quaternion<T> &, const ::std::complex<T> &)
q8 = q2-c0;
// using - (const quaternion<T> &,const quaternion<T> &)
q9 = q2-q3;
// using * (const T &, const quaternion<T> &)
q5 = f0*q2;
// using * (const quaternion<T> &, const T &)
q6 = q2*f0;
// using * (const ::std::complex<T> &, const quaternion<T> &)
q7 = c0*q2;
// using * (const quaternion<T> &, const ::std::complex<T> &)
q8 = q2*c0;
// using * (const quaternion<T> &,const quaternion<T> &)
q9 = q2*q3;
// using / (const T &, const quaternion<T> &)
q5 = f0/q2;
// using / (const quaternion<T> &, const T &)
q6 = q2/f0;
// using / (const ::std::complex<T> &, const quaternion<T> &)
q7 = c0/q2;
// using / (const quaternion<T> &, const ::std::complex<T> &)
q8 = q2/c0;
// using / (const quaternion<T> &,const quaternion<T> &)
q9 = q2/q3;
// using + (const quaternion<T> &)
q2 = +q0;
// using - (const quaternion<T> &)
q2 = -q3;
// using == (const T &, const quaternion<T> &)
f0 == q2;
// using == (const quaternion<T> &, const T &)
q2 == f0;
// using == (const ::std::complex<T> &, const quaternion<T> &)
c0 == q2;
// using == (const quaternion<T> &, const ::std::complex<T> &)
q2 == c0;
// using == (const quaternion<T> &,const quaternion<T> &)
q2 == q3;
// using != (const T &, const quaternion<T> &)
f0 != q2;
// using != (const quaternion<T> &, const T &)
q2 != f0;
// using != (const ::std::complex<T> &, const quaternion<T> &)
c0 != q2;
// using != (const quaternion<T> &, const ::std::complex<T> &)
q2 != c0;
// using != (const quaternion<T> &,const quaternion<T> &)
q2 != q3;
::std::cout << "Please input a quaternion..." << ::std::endl;
#if BOOST_INTERACTIVE_TEST_INPUT_ITERATOR
::std::cin >> q0;
if (::std::cin.fail())
{
::std::cout << "You have entered nonsense!" << ::std::endl;
}
else
{
::std::cout << "You have entered the quaternion "
<< q0 << " ." << ::std::endl;
}
#else
::std::istringstream bogus("(1,2,3,4)");
bogus >> q0;
::std::cout << "You have entered the quaternion "
<< q0 << " ." << ::std::endl;
#endif
::std::cout << "For this quaternion:" << ::std::endl;
::std::cout << "the value of "
<< "the real part is "
<< real(q0) << ::std::endl;
::std::cout << "the value of "
<< "the unreal part is "
<< unreal(q0) << ::std::endl;
::std::cout << "the value of "
<< "the sup norm is "
<< sup(q0) << ::std::endl;
::std::cout << "the value of "
<< "the l1 norm is "
<< l1(q0) << ::std::endl;
::std::cout << "the value of "
<< "the magnitude (euclidian norm) is "
<< abs(q0) << ::std::endl;
::std::cout << "the value of "
<< "the (Cayley) norm is "
<< norm(q0) << ::std::endl;
::std::cout << "the value of "
<< "the conjugate is "
<< conj(q0) << ::std::endl;
::std::cout << "the value of "
<< "the exponential is "
<< exp(q0) << ::std::endl;
::std::cout << "the value of "
<< "the cube is "
<< pow(q0,3) << ::std::endl;
::std::cout << "the value of "
<< "the cosinus is "
<< cos(q0) << ::std::endl;
::std::cout << "the value of "
<< "the sinus is "
<< sin(q0) << ::std::endl;
::std::cout << "the value of "
<< "the tangent is "
<< tan(q0) << ::std::endl;
::std::cout << "the value of "
<< "the hyperbolic cosinus is "
<< cosh(q0) << ::std::endl;
::std::cout << "the value of "
<< "the hyperbolic sinus is "
<< sinh(q0) << ::std::endl;
::std::cout << "the value of "
<< "the hyperbolic tangent is "
<< tanh(q0) << ::std::endl;
#if !defined(__GNUC__) && !defined(__COMO__)
// somehow, this does not work with either gcc or Comeau :-(
::std::cout << "the value of "
<< "the Sinus Cardinal (of index pi) is "
<< sinc_pi(q0) << ::std::endl;
::std::cout << "the value of "
<< "the Hyperbolic Sinus Cardinal (of index pi) is "
<< sinhc_pi(q0) << ::std::endl;
#endif
::std::cout << ::std::endl;
float rho = ::std::sqrt(8.0f);
float theta = ::std::atan(1.0f);
float phi1 = ::std::atan(1.0f);
float phi2 = ::std::atan(1.0f);
::std::cout << "The value of the quaternion represented "
<< "in spherical form by "
<< "rho = " << rho << " , theta = " << theta
<< " , phi1 = " << phi1 << " , phi2 = " << phi2
<< " is " << ::boost::spherical(rho, theta, phi1, phi2)
<< ::std::endl;
float alpha = ::std::atan(1.0f);
::std::cout << "The value of the quaternion represented "
<< "in semipolar form by "
<< "rho = " << rho << " , alpha = " << alpha
<< " , phi1 = " << phi1 << " , phi2 = " << phi2
<< " is " << ::boost::semipolar(rho, alpha, phi1, phi2)
<< ::std::endl;
float rho1 = 1;
float rho2 = 2;
float theta1 = 0;
float theta2 = ::std::atan(1.0f)*2;
::std::cout << "The value of the quaternion represented "
<< "in multipolar form by "
<< "rho1 = " << rho1 << " , theta1 = " << theta1
<< " , rho2 = " << rho2 << " , theta2 = " << theta2
<< " is " << ::boost::multipolar(rho1, theta1, rho2, theta2)
<< ::std::endl;
float t = 5;
float radius = ::std::sqrt(2.0f);
float longitude = ::std::atan(1.0f);
float lattitude =
::std::atan(::std::sqrt(3.0f));
::std::cout << "The value of the quaternion represented "
<< "in cylindrospherical form by "
<< "t = " << t << " , radius = " << radius
<< " , longitude = " << longitude << " , latitude = "
<< lattitude << " is "
<< ::boost::cylindrospherical(t, radius, longitude, lattitude)
<< ::std::endl;
float r = ::std::sqrt(2.0f);
float angle = ::std::atan(1.0f);
float h1 = 3;
float h2 = 4;
::std::cout << "The value of the quaternion represented "
<< "in cylindrical form by "
<< "r = " << r << " , angle = " << angle
<< " , h1 = " << h1 << " , h2 = " << h2
<< " is " << ::boost::cylindrical(r, angle, h1, h2)
<< ::std::endl;
double real_1(1);
::std::complex<double> complex_1(1);
::std::complex<double> complex_i(0,1);
::boost::quaternion<double> quaternion_1(1);
::boost::quaternion<double> quaternion_i(0,1);
::boost::quaternion<double> quaternion_j(0,0,1);
::boost::quaternion<double> quaternion_k(0,0,0,1);
::std::cout << ::std::endl;
::std::cout << "Real 1: " << real_1
<< " ; Complex 1: " << complex_1
<< " ; Quaternion 1: " << quaternion_1
<< " ." << ::std::endl;
::std::cout << "Complex i: " << complex_i
<< " ; Quaternion i: "
<< quaternion_i << " ."
<< ::std::endl;
::std::cout << "Quaternion j: " << quaternion_j
<< " ." << ::std::endl;
::std::cout << "Quaternion k: " << quaternion_k
<< " ." << ::std::endl;
::std::cout << ::std::endl;
::std::cout << "i*i: " << quaternion_i*quaternion_i << " ; ";
::std::cout << "j*j: " << quaternion_j*quaternion_j << " ; ";
::std::cout << "k*k: " << quaternion_k*quaternion_k << " ." << ::std::endl;
::std::cout << "i*j: " << quaternion_i*quaternion_j << " ; ";
::std::cout << "j*i: " << quaternion_j*quaternion_i << " ." << ::std::endl;
::std::cout << "j*k: " << quaternion_j*quaternion_k << " ; ";
::std::cout << "k*j: " << quaternion_k*quaternion_j << " ." << ::std::endl;
::std::cout << "k*i: " << quaternion_k*quaternion_i << " ; ";
::std::cout << "i*k: " << quaternion_i*quaternion_k << " ." << ::std::endl;
::std::cout << ::std::endl;
// tests for evaluation by scripts
using ::std::numeric_limits;
using ::boost::abs;
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(1,0,0,0)*
::boost::quaternion<float>(1,0,0,0)-
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,1,0,0)*
::boost::quaternion<float>(0,1,0,0)+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,0,1,0)*
::boost::quaternion<float>(0,0,1,0)+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,0,0,1)*
::boost::quaternion<float>(0,0,0,1)+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,1,0,0)*
::boost::quaternion<float>(0,0,1,0)-
::boost::quaternion<float>(0,0,0,1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,0,1,0)*
::boost::quaternion<float>(0,1,0,0)+
::boost::quaternion<float>(0,0,0,1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,0,1,0)*
::boost::quaternion<float>(0,0,0,1)-
::boost::quaternion<float>(0,1,0,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,0,0,1)*
::boost::quaternion<float>(0,0,1,0)+
::boost::quaternion<float>(0,1,0,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,0,0,1)*
::boost::quaternion<float>(0,1,0,0)-
::boost::quaternion<float>(0,0,1,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<float>(0,1,0,0)*
::boost::quaternion<float>(0,0,0,1)+
::boost::quaternion<float>(0,0,1,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<float>(0,4*::std::atan(1),0,0))+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<float>(0,0,4*::std::atan(1),0))+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<float>(0,0,0,4*::std::atan(1)))+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<float>(4)*
cos(::boost::quaternion<float>(0,::std::log(2),0,0))-
static_cast<float>(5)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<float>(4)*
cos(::boost::quaternion<float>(0,0,::std::log(2),0))-
static_cast<float>(5)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<float>(4)*
cos(::boost::quaternion<float>(0,0,0,::std::log(2)))-
static_cast<float>(5)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<float>(4)*
sin(::boost::quaternion<float>(0,::std::log(2),0,0))-
::boost::quaternion<float>(0,3,0,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<float>(4)*
sin(::boost::quaternion<float>(0,0,::std::log(2),0))-
::boost::quaternion<float>(0,0,3,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<float>(4)*
sin(::boost::quaternion<float>(0,0,0,::std::log(2)))-
::boost::quaternion<float>(0,0,0,3)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<float>(0,4*::std::atan(1),0,0))+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<float>(0,0,4*::std::atan(1),0))+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<float>(0,0,0,4*::std::atan(1)))+
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<float>(0,2*::std::atan(1),0,0))-
::boost::quaternion<float>(0,1,0,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<float>(0,0,2*::std::atan(1),0))-
::boost::quaternion<float>(0,0,1,0)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<float>(0,0,0,2*::std::atan(1)))-
::boost::quaternion<float>(0,0,0,1)) <=
numeric_limits<float>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(1,0,0,0)*
::boost::quaternion<double>(1,0,0,0)-
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,1,0,0)*
::boost::quaternion<double>(0,1,0,0)+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,0,1,0)*
::boost::quaternion<double>(0,0,1,0)+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,0,0,1)*
::boost::quaternion<double>(0,0,0,1)+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,1,0,0)*
::boost::quaternion<double>(0,0,1,0)-
::boost::quaternion<double>(0,0,0,1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,0,1,0)*
::boost::quaternion<double>(0,1,0,0)+
::boost::quaternion<double>(0,0,0,1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,0,1,0)*
::boost::quaternion<double>(0,0,0,1)-
::boost::quaternion<double>(0,1,0,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,0,0,1)*
::boost::quaternion<double>(0,0,1,0)+
::boost::quaternion<double>(0,1,0,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,0,0,1)*
::boost::quaternion<double>(0,1,0,0)-
::boost::quaternion<double>(0,0,1,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<double>(0,1,0,0)*
::boost::quaternion<double>(0,0,0,1)+
::boost::quaternion<double>(0,0,1,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<double>(0,4*::std::atan(1),0,0))+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<double>(0,0,4*::std::atan(1),0))+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<double>(0,0,0,4*::std::atan(1)))+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<double>(4)*
cos(::boost::quaternion<double>(0,::std::log(2),0,0))-
static_cast<double>(5)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<double>(4)*
cos(::boost::quaternion<double>(0,0,::std::log(2),0))-
static_cast<double>(5)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<double>(4)*
cos(::boost::quaternion<double>(0,0,0,::std::log(2)))-
static_cast<double>(5)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<double>(4)*
sin(::boost::quaternion<double>(0,::std::log(2),0,0))-
::boost::quaternion<double>(0,3,0,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<double>(4)*
sin(::boost::quaternion<double>(0,0,::std::log(2),0))-
::boost::quaternion<double>(0,0,3,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<double>(4)*
sin(::boost::quaternion<double>(0,0,0,::std::log(2)))-
::boost::quaternion<double>(0,0,0,3)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<double>(0,4*::std::atan(1),0,0))+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<double>(0,0,4*::std::atan(1),0))+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<double>(0,0,0,4*::std::atan(1)))+
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<double>(0,2*::std::atan(1),0,0))-
::boost::quaternion<double>(0,1,0,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<double>(0,0,2*::std::atan(1),0))-
::boost::quaternion<double>(0,0,1,0)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<double>(0,0,0,2*::std::atan(1)))-
::boost::quaternion<double>(0,0,0,1)) <=
numeric_limits<double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(1,0,0,0)*
::boost::quaternion<long double>(1,0,0,0)-
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,1,0,0)*
::boost::quaternion<long double>(0,1,0,0)+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,0,1,0)*
::boost::quaternion<long double>(0,0,1,0)+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,0,0,1)*
::boost::quaternion<long double>(0,0,0,1)+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,1,0,0)*
::boost::quaternion<long double>(0,0,1,0)-
::boost::quaternion<long double>(0,0,0,1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,0,1,0)*
::boost::quaternion<long double>(0,1,0,0)+
::boost::quaternion<long double>(0,0,0,1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,0,1,0)*
::boost::quaternion<long double>(0,0,0,1)-
::boost::quaternion<long double>(0,1,0,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,0,0,1)*
::boost::quaternion<long double>(0,0,1,0)+
::boost::quaternion<long double>(0,1,0,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,0,0,1)*
::boost::quaternion<long double>(0,1,0,0)-
::boost::quaternion<long double>(0,0,1,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(::boost::quaternion<long double>(0,1,0,0)*
::boost::quaternion<long double>(0,0,0,1)+
::boost::quaternion<long double>(0,0,1,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<long double>(0,4*::std::atan(1),0,0))+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<long double>(0,0,4*::std::atan(1),0))+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
exp(::boost::quaternion<long double>(0,0,0,4*::std::atan(1)))+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<long double>(4)*
cos(::boost::quaternion<long double>(0,::std::log(2),0,0))-
static_cast<long double>(5)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<long double>(4)*
cos(::boost::quaternion<long double>(0,0,::std::log(2),0))-
static_cast<long double>(5)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<long double>(4)*
cos(::boost::quaternion<long double>(0,0,0,::std::log(2)))-
static_cast<long double>(5)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<long double>(4)*
sin(::boost::quaternion<long double>(0,::std::log(2),0,0))-
::boost::quaternion<long double>(0,3,0,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<long double>(4)*
sin(::boost::quaternion<long double>(0,0,::std::log(2),0))-
::boost::quaternion<long double>(0,0,3,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
static_cast<long double>(4)*
sin(::boost::quaternion<long double>(0,0,0,::std::log(2)))-
::boost::quaternion<long double>(0,0,0,3)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<long double>(0,4*::std::atan(1),0,0))+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<long double>(0,0,4*::std::atan(1),0))+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
cosh(::boost::quaternion<long double>(0,0,0,4*::std::atan(1)))+
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<long double>(0,2*::std::atan(1),0,0))-
::boost::quaternion<long double>(0,1,0,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<long double>(0,0,2*::std::atan(1),0))-
::boost::quaternion<long double>(0,0,1,0)) <=
numeric_limits<long double>::epsilon());
BOOST_CRITICAL_TEST(abs(
sinh(::boost::quaternion<long double>(0,0,0,2*::std::atan(1)))-
::boost::quaternion<long double>(0,0,0,1)) <=
numeric_limits<long double>::epsilon());
return(::boost::exit_success);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,72 @@
<html>
<head>
<title>Boost Special Functions library</title>
<meta http-equiv="generator" content="Adobe GoLive 5">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2">
<tr>
<td bgcolor="#FFFFFF"><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" WIDTH="277" HEIGHT="86"></td>
<td><a href="../../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td>
<td><a href="../../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td>
<td><a href="../../../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td>
<td><a href="../../../more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td>
<td><a href="../../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td>
</tr>
</table>
<h2>Special Functions library</h2>
<p>The Special Functions library is a stop-gap collection of numerical functions, some of which are needed for our implementation of <a href="../quaternion/index.htm">quaternions</a> and <a href="../octonion/index.htm">octonions</a>. <ul>
<li><a href="special_functions.html">Documentation</a></li>
<li>Header <a href="../../../boost/math/special_functions/atanh.hpp">atanh.hpp</a></li>
<li>Header <a href="../../../boost/math/special_functions/sinc.hpp">sinc.hpp</a>
<li>Header <a href="../../../boost/math/special_functions/sinhc.hpp">sinhc.hpp</a>
<li>Test program <a href="special_functions_test.cpp">special_functions_test.cpp</a></li>
<li>Download <a href="../../../more/download.html"> all of Boost</a>.</li>
<li>Submitted by Hubert Holin.</li>
</ul>
<h3>Comments</h3>
<p>Compiles and runs under MetroWerk's CodeWarrior Pro 6.</p>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %b %Y" startspan -->07 June 2001<!--webbot bot="Timestamp" endspan i-checksum="15233" -->
</p>
</body>
</html>

View File

@@ -0,0 +1,307 @@
-inf -10 -10
-inf -9.8 -9.8
-inf -9.6 -9.6
-inf -9.4 -9.4
-inf -9.2 -9.2
-8.66434 -9 -9
-8.66434 -8.8 -8.8
-8.66434 -8.6 -8.6
-8.31777 -8.4 -8.4
-8.11503 -8.2 -8.2
-7.97119 -8 -8
-7.76846 -7.8 -7.8
-7.62462 -7.6 -7.6
-7.38187 -7.4 -7.4
-7.19212 -7.2 -7.2
-6.99824 -7 -7
-6.7955 -6.8 -6.8
-6.60077 -6.6 -6.6
-6.39804 -6.4 -6.4
-6.20071 -6.2 -6.2
-6.0004 -6 -6
-5.79929 -5.8 -5.8
-5.59981 -5.6 -5.6
-5.40035 -5.4 -5.4
-5.20006 -5.2 -5.2
-5.0001 -5 -5
-4.8001 -4.8 -4.8
-4.6 -4.6 -4.6
-4.4 -4.4 -4.4
-4.19997 -4.2 -4.2
-4.00002 -4 -4
-3.8 -3.8 -3.8
-3.59999 -3.6 -3.6
-3.39999 -3.4 -3.4
-3.2 -3.2 -3.2
-3 -3 -3
-2.8 -2.8 -2.8
-2.6 -2.6 -2.6
-2.4 -2.4 -2.4
-2.2 -2.2 -2.2
-2 -2 -2
-1.8 -1.8 -1.8
-1.6 -1.6 -1.6
-1.4 -1.4 -1.4
-1.2 -1.2 -1.2
-1 -1 -1
-0.8 -0.8 -0.8
-0.6 -0.6 -0.6
-0.4 -0.4 -0.4
-0.2 -0.2 -0.2
0 0 0
0.2 0.2 0.2
0.4 0.4 0.4
0.6 0.6 0.6
0.8 0.8 0.8
1 1 1
1.2 1.2 1.2
1.4 1.4 1.4
1.6 1.6 1.6
1.8 1.8 1.8
2 2 2
2.2 2.2 2.2
2.4 2.4 2.4
2.6 2.6 2.6
2.8 2.8 2.8
3 3 3
3.2 3.2 3.2
3.39999 3.4 3.4
3.59999 3.6 3.6
3.8 3.8 3.8
4.00002 4 4
4.19997 4.2 4.2
4.4 4.4 4.4
4.6 4.6 4.6
4.8001 4.8 4.8
5.0001 5 5
5.20006 5.2 5.2
5.40035 5.4 5.4
5.59981 5.6 5.6
5.79929 5.8 5.8
6.0004 6 6
6.20071 6.2 6.2
6.39804 6.4 6.4
6.60077 6.6 6.6
6.7955 6.8 6.8
6.99824 7 7
7.19212 7.2 7.2
7.38187 7.4 7.4
7.62462 7.6 7.6
7.76846 7.8 7.8
7.97119 8 8
8.11503 8.2 8.2
8.31777 8.4 8.4
8.66434 8.6 8.6
8.66434 8.8 8.8
8.66434 9 9
inf 9.2 9.2
inf 9.4 9.4
inf 9.6 9.6
inf 9.8 9.8
inf 10 10
0.841471 0.841471 0.841471
0.847446 0.847446 0.847446
0.853325 0.853325 0.853325
0.859104 0.859104 0.859104
0.864784 0.864784 0.864784
0.870363 0.870363 0.870363
0.87584 0.87584 0.87584
0.881212 0.881212 0.881212
0.88648 0.88648 0.88648
0.891641 0.891641 0.891641
0.896695 0.896695 0.896695
0.90164 0.90164 0.90164
0.906476 0.906476 0.906476
0.9112 0.9112 0.9112
0.915812 0.915812 0.915812
0.920311 0.920311 0.920311
0.924696 0.924696 0.924696
0.928965 0.928965 0.928965
0.933118 0.933118 0.933118
0.937153 0.937153 0.937153
0.941071 0.941071 0.941071
0.944869 0.944869 0.944869
0.948547 0.948547 0.948547
0.952104 0.952104 0.952104
0.955539 0.955539 0.955539
0.958851 0.958851 0.958851
0.96204 0.96204 0.96204
0.965105 0.965105 0.965105
0.968044 0.968044 0.968044
0.970858 0.970858 0.970858
0.973546 0.973546 0.973546
0.976107 0.976106 0.976106
0.97854 0.97854 0.97854
0.980844 0.980844 0.980844
0.98302 0.983021 0.983021
0.985067 0.985067 0.985067
0.986984 0.986984 0.986984
0.988771 0.988771 0.988771
0.990428 0.990428 0.990428
0.991953 0.991953 0.991953
0.993347 0.993347 0.993347
0.994609 0.994609 0.994609
0.995739 0.995739 0.995739
0.996737 0.996737 0.996737
0.997602 0.997602 0.997602
0.998334 0.998334 0.998334
0.998934 0.998934 0.998934
0.9994 0.9994 0.9994
0.999733 0.999733 0.999733
0.999933 0.999933 0.999933
1 1 1
0.999933 0.999933 0.999933
0.999733 0.999733 0.999733
0.9994 0.9994 0.9994
0.998934 0.998934 0.998934
0.998334 0.998334 0.998334
0.997602 0.997602 0.997602
0.996737 0.996737 0.996737
0.995739 0.995739 0.995739
0.994609 0.994609 0.994609
0.993347 0.993347 0.993347
0.991953 0.991953 0.991953
0.990428 0.990428 0.990428
0.988771 0.988771 0.988771
0.986984 0.986984 0.986984
0.985067 0.985067 0.985067
0.98302 0.983021 0.983021
0.980844 0.980844 0.980844
0.97854 0.97854 0.97854
0.976107 0.976106 0.976106
0.973546 0.973546 0.973546
0.970858 0.970858 0.970858
0.968044 0.968044 0.968044
0.965105 0.965105 0.965105
0.96204 0.96204 0.96204
0.958851 0.958851 0.958851
0.955539 0.955539 0.955539
0.952104 0.952104 0.952104
0.948547 0.948547 0.948547
0.944869 0.944869 0.944869
0.941071 0.941071 0.941071
0.937153 0.937153 0.937153
0.933118 0.933118 0.933118
0.928965 0.928965 0.928965
0.924696 0.924696 0.924696
0.920311 0.920311 0.920311
0.915812 0.915812 0.915812
0.9112 0.9112 0.9112
0.906476 0.906476 0.906476
0.90164 0.90164 0.90164
0.896695 0.896695 0.896695
0.891641 0.891641 0.891641
0.88648 0.88648 0.88648
0.881212 0.881212 0.881212
0.87584 0.87584 0.87584
0.870363 0.870363 0.870363
0.864784 0.864784 0.864784
0.859104 0.859104 0.859104
0.853325 0.853325 0.853325
0.847446 0.847446 0.847446
0.841471 0.841471 0.841471
1.1752 1.1752 1.1752
1.16793 1.16793 1.16793
1.16084 1.16084 1.16084
1.15391 1.15391 1.15391
1.14716 1.14716 1.14716
1.14057 1.14057 1.14057
1.13416 1.13416 1.13416
1.12791 1.12791 1.12791
1.12182 1.12182 1.12182
1.1159 1.1159 1.1159
1.11013 1.11013 1.11013
1.10453 1.10453 1.10453
1.09909 1.09909 1.09909
1.0938 1.0938 1.0938
1.08867 1.08867 1.08867
1.08369 1.08369 1.08369
1.07887 1.07887 1.07887
1.0742 1.0742 1.0742
1.06968 1.06968 1.06968
1.06531 1.06531 1.06531
1.06109 1.06109 1.06109
1.05702 1.05702 1.05702
1.05309 1.05309 1.05309
1.04931 1.04931 1.04931
1.04568 1.04568 1.04568
1.04219 1.04219 1.04219
1.03884 1.03884 1.03884
1.03564 1.03564 1.03564
1.03258 1.03258 1.03258
1.02966 1.02966 1.02966
1.02688 1.02688 1.02688
1.02424 1.02424 1.02424
1.02174 1.02174 1.02174
1.01938 1.01938 1.01938
1.01715 1.01715 1.01715
1.01507 1.01507 1.01507
1.01312 1.01312 1.01312
1.0113 1.0113 1.0113
1.00963 1.00963 1.00963
1.00809 1.00809 1.00809
1.00668 1.00668 1.00668
1.00541 1.00541 1.00541
1.00427 1.00427 1.00427
1.00327 1.00327 1.00327
1.0024 1.0024 1.0024
1.00167 1.00167 1.00167
1.00107 1.00107 1.00107
1.0006 1.0006 1.0006
1.00027 1.00027 1.00027
1.00007 1.00007 1.00007
1 1 1
1.00007 1.00007 1.00007
1.00027 1.00027 1.00027
1.0006 1.0006 1.0006
1.00107 1.00107 1.00107
1.00167 1.00167 1.00167
1.0024 1.0024 1.0024
1.00327 1.00327 1.00327
1.00427 1.00427 1.00427
1.00541 1.00541 1.00541
1.00668 1.00668 1.00668
1.00809 1.00809 1.00809
1.00963 1.00963 1.00963
1.0113 1.0113 1.0113
1.01312 1.01312 1.01312
1.01507 1.01507 1.01507
1.01715 1.01715 1.01715
1.01938 1.01938 1.01938
1.02174 1.02174 1.02174
1.02424 1.02424 1.02424
1.02688 1.02688 1.02688
1.02966 1.02966 1.02966
1.03258 1.03258 1.03258
1.03564 1.03564 1.03564
1.03884 1.03884 1.03884
1.04219 1.04219 1.04219
1.04568 1.04568 1.04568
1.04931 1.04931 1.04931
1.05309 1.05309 1.05309
1.05702 1.05702 1.05702
1.06109 1.06109 1.06109
1.06531 1.06531 1.06531
1.06968 1.06968 1.06968
1.0742 1.0742 1.0742
1.07887 1.07887 1.07887
1.08369 1.08369 1.08369
1.08867 1.08867 1.08867
1.0938 1.0938 1.0938
1.09909 1.09909 1.09909
1.10453 1.10453 1.10453
1.11013 1.11013 1.11013
1.1159 1.1159 1.1159
1.12182 1.12182 1.12182
1.12791 1.12791 1.12791
1.13416 1.13416 1.13416
1.14057 1.14057 1.14057
1.14716 1.14716 1.14716
1.15391 1.15391 1.15391
1.16084 1.16084 1.16084
1.16793 1.16793 1.16793
1.1752 1.1752 1.1752
no errors detected

View File

@@ -0,0 +1,120 @@
<html>
<head>
<title>Special Functions Documentation</title>
<meta http-equiv="generator" content="Adobe GoLive 5">
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1><img src="../../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Special Functions library</h1>
<ul>
<li><a href="#Acknowledgements">Acknowledgements</a>
<li><a href="#Header File">Header Files</a>
<li><a href="#Test Program">Test Program</a>
<li><a href="#Synopsis">Synopsis</a>
<li><a href="#Functions">Functions</a>
<li><a href="#History">History</a>
</ul>
<p>The Special Functions library currently provides three templated special functions, in namespace boost. Two of these (sinc_pi and sinhc_pi) are needed by our implementation of quaternions and octonions.</p>
<p>The function atanh is entirely classical, the function sinc_pi sees heavy use in signal processing tasks, and the function sinhc_pi is an <cite>ad'hoc</cite> function whose naming is modelled on sinc_pi and hyperbolic functions.</p>
<p>The exponential function is defined, for all object for which this makes sense, as the power series <img src="graphics/special_functions_blurb.h1.jpeg" width="75" height="32" naturalsizeflag="3" align=absmiddle><font color="#000000">, with <img src="graphics/special_functions_blurb.h2.jpeg" width="83" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> (and <img src="graphics/special_functions_blurb.h3.jpeg" width="26" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> by definition) being the factorial of <img src="graphics/special_functions_blurb.h4.jpeg" width="9" height="9" naturalsizeflag="3" align=absmiddle></font><font color="#000000">. In particular, the exponential function is well defined for real numbers, complex number, quaternions, octonions, and matrices of complex numbers, among others.</font></p>
<div align="center">
<p><img src="graphics/exp_on_R.png" width="502" height="330" border="0"></p>
<p><samp>Graph of exp on R</samp></p>
</div>
<p></p>
<div align="center">
<p><img src="graphics/Re(exp)_on_C.png" width="374" height="249" border="0"><img src="graphics/Im(exp)_on_C.png" width="374" height="249" border="0"></p>
<p><samp>Real and Imaginary parts of exp on C</samp></p>
</div>
<p><font color="#000000">The hyperbolic functions are defined as power series which can be computed (for reals, complex, quaternions and octonions) as:</font></p>
<p><font color="#000000">&nbsp;</font></p>
<p><font color="#000000">Hyperbolic cosinus: <img src="graphics/special_functions_blurb.h5.jpeg" width="144" height="29" naturalsizeflag="3" align=absmiddle></font></p>
<p><font color="#000000">Hyperbolic sinus: <img src="graphics/special_functions_blurb.h6.jpeg" width="142" height="29" naturalsizeflag="3" align=absmiddle></font></p>
<p><font color="#000000">Hyperbolic tangent: <img src="graphics/special_functions_blurb.h7.jpeg" width="90" height="32" naturalsizeflag="3" align=absmiddle></font></p>
<p></p>
<div align="center">
<p><font color="#000000">&nbsp;<img src="graphics/trigonometric.png" width="502" height="330" border="0"></font></p>
<p><samp>Trigonometric functions on R (cos: purple; sin: red; tan: blue)</samp></p>
<p><img src="graphics/hyperbolic.png" width="502" height="330" border="0"></p>
<p><samp>Hyperbolic functions on r (cosh: purple; sinh: red; tanh: blue)</samp></p>
</div>
<p><font color="#000000">The hyperbolic sinus is one to one on the set of real numbers, with range the full set of reals, while the hyperbolic tangent is also one to one on the set of real numbers but with range <img src="graphics/special_functions_blurb.h8.jpeg" width="46" height="16" naturalsizeflag="3" align=absmiddle></font><font color="#000000">, and therefore both have inverses.</font></p>
<p><font color="#000000">The inverse of the hyperbolic tangent is called the Argument hyperbolic tangent, and can be computed as <img src="graphics/special_functions_blurb.h9.jpeg" width="109" height="44" naturalsizeflag="3" align=absmiddle></font><font color="#000000">.</font></p>
<p><font color="#000000">The Sinus Cardinal family of functions is defined by the family of indices <img src="graphics/special_functions_blurb.10.jpeg" width="27" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> by <img src="graphics/special_functions_blurb.11.jpeg" width="99" height="58" naturalsizeflag="3" align=absmiddle></font><font color="#000000">. It is also an entire function (sum of a power series).</font></p>
<p><font color="#000000">We define, by analogy, the Hyperbolic Sinus Cardinal family of functions is defined by the family of indices <img src="graphics/special_functions_blurb.12.jpeg" width="27" height="12" naturalsizeflag="3" align=absmiddle></font><font color="#000000"> by <img src="graphics/special_functions_blurb.13.jpeg" width="111" height="58" naturalsizeflag="3" align=absmiddle></font><font color="#000000">. It, too, is an entire function.</font></p>
<div align="center">
<p><img src="graphics/sinc_pi_and_sinhc_pi_on_R.png" width="502" height="330" border="0"></p>
<p><samp>Sinus Cardinal of index pi (purple) and Hyperbolic Sinus Cardinal of index pi (red) on R</samp></p>
</div>
<h2><a name="Acknowledgements"></a>Acknowledgements</h2>
<p>The mathematical text has been typeset with <a href="http://www.nisus-soft.com/">Nisus Writer</a>, and the illustrations have been made with <a href="http://www.pacifict.com/">Graphing Calculator</a>. Jens Maurer was the Review Manager for this library. More acknowledgements in the History section. Thank you to all who contributed to the discution about this library.</p>
<h2><a name="Header File"></a>Header Files</h2>
<p>The interface and implementation for each function (or forms of a function) are both supplied by one header file:</p>
<ul>
<li type="disc"><a href="../../../boost/math/special_functions/atanh.hpp">atahn.hpp</a>
<li type="disc"><a href="../../../boost/math/special_functions/sinc.hpp">sinc.hpp</a>
<li type="disc"><a href="../../../boost/math/special_functions/sinhc.hpp">sinhc.hpp</a>
</ul>
<h2><a name="Test Program"></a>Test Program</h2>
<p>The <a href="special_functions_test.cpp">special_functions_test.cpp</a> test program tests the functions for float, double and long double arguments (<a href="output.txt">sample output</a>).</p>
<p>It has been compiled and runs without error with the following C++ compilers:</p>
<blockquote>
<ul>
<li>MetroWerk's CodeWarrior Pro 6 on a Mac on a PowerPC G3
</ul>
</blockquote>
<h2><a name="Synopsis"></a>Synopsis</h2>
<pre><code>namespace boost
{
template&lt;typename T&gt; inline T <a href="#atanh">atanh</a>(const T x);
template&lt;typename T&gt; inline T <a href="#sinc_pi">sinc_pi</a>(const T x);
template&lt;typename T, template&lt;typename&gt; class U&gt; inline U&lt;T&gt; <a href="#sinc_pi">sinc_pi</a>(const U&lt;T&gt; x);
template&lt;typename T&gt; inline T <a href="#sinhc_pi">sinhc_pi</a>(const T x);
template&lt;typename T, template&lt;typename&gt; class U&gt; inline U&lt;T&gt; <a href="#sinhc_pi">sinhc_pi</a>(const U&lt;T&gt; x);
}</code></pre>
<h2><a name="Functions"></a>Functions</h2>
<p>The functions implemented here can throw standard exceptions, but no exception specification has been made.</p>
<h3><a name="atanh"></a>atanh</h3>
<pre><code>template&lt;typename T&gt; inline T <strong>atanh</strong>(const T x);</code></pre>
<blockquote>
<p>Computes the reciprocal of the hyperbolic tangent function, at <code>x</code>.</p>
<p>If <code>x</code> is outside the range ] -1 ; +1 [ , an <code>out_of_range</code> exception is generated.</p>
<p>For the value -1 , minus infinity is returned (if the system allow, otherwise an <code>out_of_range</code> exception is generated).</p>
<p>For the value +1 , plus infinity is returned (if the system allow, otherwise an <code>out_of_range</code> exception is generated).</p>
</blockquote>
<h3><a name="sinc_pi"></a>sinc_pi</h3>
<pre><code>template&lt;typename T&gt; inline T <strong>sinc_pi</strong>(const T x);</code></pre>
<pre><code>template&lt;typename T, template&lt;typename&gt; class U&gt; inline U&lt;T&gt; <strong>sinc_pi</strong>(const U&lt;T&gt; x);</code></pre>
<blockquote>
<p>Computes the Sinus Cardinal of <code>x</code>. The second form is for complexes, quaternions, octonions...</p>
</blockquote>
<h3><a name="sinhc_pi"></a>sinhc_pi</h3>
<pre><code>template&lt;typename T&gt; inline T <strong>sinhc_pi</strong>(const T x);</code></pre>
<pre><code>template&lt;typename T, template&lt;typename&gt; class U&gt; inline U&lt;T&gt; <strong>sinhc_pi</strong>(const U&lt;T&gt; x);</code></pre>
<blockquote>
<p>Computes the Hyperbolic Sinus Cardinal of <code>x</code>. The second form is for complexes, quaternions, octonions...</p>
</blockquote>
<h2><a name="History"></a>History</h2>
<ul>
<li>1.3.1 - 07/06/2001:(end of Boost review) split <code>special_functions.hpp</code> into <code>atanh.hpp</code>, <code>sinc.hpp</code> and <code>sinhc.hpp</code>; improved efficiency of <code>atanh</code> with compile-time technique (Daryle Walker); improved accuracy of all functions near zero (Peter Schmitteckert).
<li>1.3.0 - 26/03/2001: support for complexes &amp; all, for cardinal functions.
<li>1.2.0 - 31/01/2001: minor modifications for Koenig lookup.
<li>1.1.0 - 23/01/2001: boostification.
<li>1.0.0 - 10/08/1999: first public version.
</ul>
<hr>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->07 June 2001<!--webbot bot="Timestamp" endspan i-checksum="32118" --></p>
<p>&copy; Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This software is provided &quot;as is&quot; without express or implied&nbsp; warranty, and with no claim as to its suitability for any purpose.</p>
</body>
</html>

View File

@@ -0,0 +1,151 @@
// test file for special_functions.hpp
// (C) Copyright Hubert Holin 2001. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
#include <iostream>
#include <iomanip>
#include <boost/math/special_functions/atanh.hpp>
#include <boost/math/special_functions/sinc.hpp>
#include <boost/math/special_functions/sinhc.hpp>
#define BOOST_INCLUDE_MAIN // for testing, include rather than link
#include <boost/test/test_tools.hpp>
int test_main(int, char *[])
{
using ::std::abs;
using ::std::tanh;
using ::std::log;
using ::std::numeric_limits;
using ::boost::atanh;
using ::boost::sinc_pi;
using ::boost::sinhc_pi;
// tests for evaluation by humans
for (int i = 0; i <= 100; i++)
{
::std::cout << ::std::setw(15)
<< atanh<float>(tanh(static_cast<float>(i-50)/
static_cast<float>(5)))
<< ::std::setw(15)
<< atanh<double>(tanh(static_cast<double>(i-50)/
static_cast<double>(5)))
<< ::std::setw(15)
<< atanh<long double>(tanh(static_cast<long double>(i-50)/
static_cast<long double>(5)))
<< ::std::endl;
}
::std::cout << ::std::endl;
for (int i = 0; i <= 100; i++)
{
::std::cout << ::std::setw(15)
<< sinc_pi<float>(static_cast<float>(i-50)/
static_cast<float>(50))
<< ::std::setw(15)
<< sinc_pi<double>(static_cast<double>(i-50)/
static_cast<double>(50))
<< ::std::setw(15)
<< sinc_pi<long double>(static_cast<long double>(i-50)/
static_cast<long double>(50))
<< ::std::endl;
}
::std::cout << ::std::endl;
for (int i = 0; i <= 100; i++)
{
::std::cout << ::std::setw(15)
<< sinhc_pi<float>(static_cast<float>(i-50)/
static_cast<float>(50))
<< ::std::setw(15)
<< sinhc_pi<double>(static_cast<double>(i-50)/
static_cast<double>(50))
<< ::std::setw(15)
<< sinhc_pi<long double>(static_cast<long double>(i-50)/
static_cast<long double>(50))
<< ::std::endl;
}
::std::cout << ::std::endl;
// tests for evaluation by scripts
BOOST_TEST(abs(atanh<float>(static_cast<float>(0))) <=
numeric_limits<float>::epsilon());
BOOST_TEST(abs(atanh<double>(static_cast<double>(0))) <=
numeric_limits<double>::epsilon());
BOOST_TEST(abs(atanh<long double>(static_cast<long double>(0))) <=
numeric_limits<long double>::epsilon());
BOOST_TEST(abs(atanh<float>(static_cast<float>(3)/5)-
log(static_cast<float>(2))) <=
numeric_limits<float>::epsilon());
BOOST_TEST(abs(atanh<double>(static_cast<double>(3)/5)-
log(static_cast<double>(2))) <=
numeric_limits<double>::epsilon());
BOOST_TEST(abs(atanh<long double>(static_cast<long double>(3)/5)-
log(static_cast<long double>(2))) <=
numeric_limits<long double>::epsilon());
BOOST_TEST(abs(atanh<float>(static_cast<float>(-3)/5)+
log(static_cast<float>(2))) <=
numeric_limits<float>::epsilon());
BOOST_TEST(abs(atanh<double>(static_cast<double>(-3)/5)+
log(static_cast<double>(2))) <=
numeric_limits<double>::epsilon());
BOOST_TEST(abs(atanh<long double>(static_cast<long double>(-3)/5)+
log(static_cast<long double>(2))) <=
numeric_limits<long double>::epsilon());
BOOST_TEST(abs(sinc_pi<float>(static_cast<float>(0))-
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_TEST(abs(sinc_pi<double>(static_cast<double>(0))-
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_TEST(abs(sinc_pi<long double>(static_cast<long double>(0))-
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
BOOST_TEST(abs(sinhc_pi<float>(static_cast<float>(0))-
static_cast<float>(1)) <=
numeric_limits<float>::epsilon());
BOOST_TEST(abs(sinhc_pi<double>(static_cast<double>(0))-
static_cast<double>(1)) <=
numeric_limits<double>::epsilon());
BOOST_TEST(abs(sinhc_pi<long double>(static_cast<long double>(0))-
static_cast<long double>(1)) <=
numeric_limits<long double>::epsilon());
return(::boost::exit_success);
}