]>
Commit | Line | Data |
---|---|---|
1 | [def __R ['[*R]]] | |
2 | [def __C ['[*C]]] | |
3 | [def __H ['[*H]]] | |
4 | [def __O ['[*O]]] | |
5 | [def __R3 ['[*'''R<superscript>3</superscript>''']]] | |
6 | [def __R4 ['[*'''R<superscript>4</superscript>''']]] | |
7 | [def __quadrulple ('''α,β,γ,δ''')] | |
8 | [def __quat_formula ['[^q = '''α + βi + γj + δk''']]] | |
9 | [def __quat_complex_formula ['[^q = ('''α + βi) + (γ + δi)j''' ]]] | |
10 | [def __not_equal ['[^xy '''≠''' yx]]] | |
11 | ||
12 | [mathpart quaternions Quaternions] | |
13 | ||
14 | [section:quat_overview Overview] | |
15 | ||
16 | Quaternions are a relative of complex numbers. | |
17 | ||
18 | Quaternions are in fact part of a small hierarchy of structures built | |
19 | upon the real numbers, which comprise only the set of real numbers | |
20 | (traditionally named __R), the set of complex numbers (traditionally named __C), | |
21 | the set of quaternions (traditionally named __H) and the set of octonions | |
22 | (traditionally named __O), which possess interesting mathematical properties | |
23 | (chief among which is the fact that they are ['division algebras], | |
24 | ['i.e.] where the following property is true: if ['[^y]] is an element of that | |
25 | algebra and is [*not equal to zero], then ['[^yx = yx']], where ['[^x]] and ['[^x']] | |
26 | denote elements of that algebra, implies that ['[^x = x']]). | |
27 | Each member of the hierarchy is a super-set of the former. | |
28 | ||
29 | One of the most important aspects of quaternions is that they provide an | |
30 | efficient way to parameterize rotations in __R3 (the usual three-dimensional space) | |
31 | and __R4. | |
32 | ||
33 | In practical terms, a quaternion is simply a quadruple of real numbers __quadrulple, | |
34 | which we can write in the form __quat_formula, where ['[^i]] is the same object as for complex numbers, | |
35 | and ['[^j]] and ['[^k]] are distinct objects which play essentially the same kind of role as ['[^i]]. | |
36 | ||
37 | An addition and a multiplication is defined on the set of quaternions, | |
38 | which generalize their real and complex counterparts. The main novelty | |
39 | here is that [*the multiplication is not commutative] (i.e. there are | |
40 | quaternions ['[^x]] and ['[^y]] such that __not_equal). A good mnemotechnical way of remembering | |
41 | things is by using the formula ['[^i*i = j*j = k*k = -1]]. | |
42 | ||
43 | Quaternions (and their kin) are described in far more details in this | |
44 | other [@../quaternion/TQE.pdf document] | |
45 | (with [@../quaternion/TQE_EA.pdf errata and addenda]). | |
46 | ||
47 | Some traditional constructs, such as the exponential, carry over without | |
48 | too much change into the realms of quaternions, but other, such as taking | |
49 | a square root, do not. | |
50 | ||
51 | [endsect] | |
52 | ||
53 | [section:quat_header Header File] | |
54 | ||
55 | The interface and implementation are both supplied by the header file | |
56 | [@../../../../boost/math/quaternion.hpp quaternion.hpp]. | |
57 | ||
58 | [endsect] | |
59 | ||
60 | [section:quat_synopsis Synopsis] | |
61 | ||
62 | namespace boost{ namespace math{ | |
63 | ||
64 | template<typename T> class ``[link math_toolkit.quat quaternion]``; | |
65 | template<> class ``[link math_toolkit.spec quaternion<float>]``; | |
66 | template<> class ``[link math_quaternion_double quaternion<double>]``; | |
67 | template<> class ``[link math_quaternion_long_double quaternion<long double>]``; | |
68 | ||
69 | // operators | |
70 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_addition_operators operator +]`` (T const & lhs, quaternion<T> const & rhs); | |
71 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_addition_operators operator +]`` (quaternion<T> const & lhs, T const & rhs); | |
72 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_addition_operators operator +]`` (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
73 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_addition_operators operator +]`` (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
74 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_addition_operators operator +]`` (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
75 | ||
76 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_subtraction_operators operator -]`` (T const & lhs, quaternion<T> const & rhs); | |
77 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_subtraction_operators operator -]`` (quaternion<T> const & lhs, T const & rhs); | |
78 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_subtraction_operators operator -]`` (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
79 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_subtraction_operators operator -]`` (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
80 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_subtraction_operators operator -]`` (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
81 | ||
82 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_multiplication_operators operator *]`` (T const & lhs, quaternion<T> const & rhs); | |
83 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_multiplication_operators operator *]`` (quaternion<T> const & lhs, T const & rhs); | |
84 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_multiplication_operators operator *]`` (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
85 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_multiplication_operators operator *]`` (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
86 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_multiplication_operators operator *]`` (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
87 | ||
88 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_division_operators operator /]`` (T const & lhs, quaternion<T> const & rhs); | |
89 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_division_operators operator /]`` (quaternion<T> const & lhs, T const & rhs); | |
90 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_division_operators operator /]`` (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
91 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_division_operators operator /]`` (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
92 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.binary_division_operators operator /]`` (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
93 | ||
94 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.unary_plus operator +]`` (quaternion<T> const & q); | |
95 | template<typename T> quaternion<T> ``[link math_toolkit.quat_non_mem.unary_minus operator -]`` (quaternion<T> const & q); | |
96 | ||
97 | template<typename T> bool ``[link math_toolkit.quat_non_mem.equality_operators operator ==]`` (T const & lhs, quaternion<T> const & rhs); | |
98 | template<typename T> bool ``[link math_toolkit.quat_non_mem.equality_operators operator ==]`` (quaternion<T> const & lhs, T const & rhs); | |
99 | template<typename T> bool ``[link math_toolkit.quat_non_mem.equality_operators operator ==]`` (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
100 | template<typename T> bool ``[link math_toolkit.quat_non_mem.equality_operators operator ==]`` (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
101 | template<typename T> bool ``[link math_toolkit.quat_non_mem.equality_operators operator ==]`` (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
102 | ||
103 | template<typename T> bool ``[link math_toolkit.quat_non_mem.inequality_operators operator !=]`` (T const & lhs, quaternion<T> const & rhs); | |
104 | template<typename T> bool ``[link math_toolkit.quat_non_mem.inequality_operators operator !=]`` (quaternion<T> const & lhs, T const & rhs); | |
105 | template<typename T> bool ``[link math_toolkit.quat_non_mem.inequality_operators operator !=]`` (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
106 | template<typename T> bool ``[link math_toolkit.quat_non_mem.inequality_operators operator !=]`` (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
107 | template<typename T> bool ``[link math_toolkit.quat_non_mem.inequality_operators operator !=]`` (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
108 | ||
109 | template<typename T, typename charT, class traits> | |
110 | ::std::basic_istream<charT,traits>& ``[link math_toolkit.quat_non_mem.stream_extractor operator >>]`` (::std::basic_istream<charT,traits> & is, quaternion<T> & q); | |
111 | ||
112 | template<typename T, typename charT, class traits> | |
113 | ::std::basic_ostream<charT,traits>& operator ``[link math_toolkit.quat_non_mem.stream_inserter operator <<]`` (::std::basic_ostream<charT,traits> & os, quaternion<T> const & q); | |
114 | ||
115 | // values | |
116 | template<typename T> T ``[link math_toolkit.value_op.real_and_unreal real]``(quaternion<T> const & q); | |
117 | template<typename T> quaternion<T> ``[link math_toolkit.value_op.real_and_unreal unreal]``(quaternion<T> const & q); | |
118 | ||
119 | template<typename T> T ``[link math_toolkit.value_op.sup sup]``(quaternion<T> const & q); | |
120 | template<typename T> T ``[link math_toolkit.value_op.l1 l1]``(quaternion<T> const & q); | |
121 | template<typename T> T ``[link math_toolkit.value_op.abs abs]``(quaternion<T> const & q); | |
122 | template<typename T> T ``[link math_toolkit.value_op.norm norm]``(quaternion<T>const & q); | |
123 | template<typename T> quaternion<T> ``[link math_toolkit.value_op.conj conj]``(quaternion<T> const & q); | |
124 | ||
125 | template<typename T> quaternion<T> ``[link math_quaternions.creation_spherical]``(T const & rho, T const & theta, T const & phi1, T const & phi2); | |
126 | template<typename T> quaternion<T> ``[link math_quaternions.creation_semipolar semipolar]``(T const & rho, T const & alpha, T const & theta1, T const & theta2); | |
127 | template<typename T> quaternion<T> ``[link math_quaternions.creation_multipolar multipolar]``(T const & rho1, T const & theta1, T const & rho2, T const & theta2); | |
128 | template<typename T> quaternion<T> ``[link math_quaternions.creation_cylindrospherical cylindrospherical]``(T const & t, T const & radius, T const & longitude, T const & latitude); | |
129 | template<typename T> quaternion<T> ``[link math_quaternions.creation_cylindrical cylindrical]``(T const & r, T const & angle, T const & h1, T const & h2); | |
130 | ||
131 | // transcendentals | |
132 | template<typename T> quaternion<T> ``[link math_toolkit.trans.exp exp]``(quaternion<T> const & q); | |
133 | template<typename T> quaternion<T> ``[link math_toolkit.trans.cos cos]``(quaternion<T> const & q); | |
134 | template<typename T> quaternion<T> ``[link math_toolkit.trans.sin sin]``(quaternion<T> const & q); | |
135 | template<typename T> quaternion<T> ``[link math_toolkit.trans.tan tan]``(quaternion<T> const & q); | |
136 | template<typename T> quaternion<T> ``[link math_toolkit.trans.cosh cosh]``(quaternion<T> const & q); | |
137 | template<typename T> quaternion<T> ``[link math_toolkit.trans.sinh sinh]``(quaternion<T> const & q); | |
138 | template<typename T> quaternion<T> ``[link math_toolkit.trans.tanh tanh]``(quaternion<T> const & q); | |
139 | template<typename T> quaternion<T> ``[link math_toolkit.trans.pow pow]``(quaternion<T> const & q, int n); | |
140 | ||
141 | } // namespace math | |
142 | } // namespace boost | |
143 | ||
144 | [endsect] | |
145 | ||
146 | [section:quat Template Class quaternion] | |
147 | ||
148 | namespace boost{ namespace math{ | |
149 | ||
150 | template<typename T> | |
151 | class quaternion | |
152 | { | |
153 | public: | |
154 | ||
155 | typedef T ``[link math_toolkit.mem_typedef value_type]``; | |
156 | ||
157 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(T const & requested_a = T(), T const & requested_b = T(), T const & requested_c = T(), T const & requested_d = T()); | |
158 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(::std::complex<T> const & z0, ::std::complex<T> const & z1 = ::std::complex<T>()); | |
159 | template<typename X> | |
160 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<X> const & a_recopier); | |
161 | ||
162 | T ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts real]``() const; | |
163 | quaternion<T> ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts unreal]``() const; | |
164 | T ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_1]``() const; | |
165 | T ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_2]``() const; | |
166 | T ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_3]``() const; | |
167 | T ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_4]``() const; | |
168 | ::std::complex<T> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_1]``() const; | |
169 | ::std::complex<T> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_2]``() const; | |
170 | ||
171 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<T> const & a_affecter); | |
172 | template<typename X> | |
173 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<X> const & a_affecter); | |
174 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(T const & a_affecter); | |
175 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(::std::complex<T> const & a_affecter); | |
176 | ||
177 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(T const & rhs); | |
178 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(::std::complex<T> const & rhs); | |
179 | template<typename X> | |
180 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(quaternion<X> const & rhs); | |
181 | ||
182 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(T const & rhs); | |
183 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(::std::complex<T> const & rhs); | |
184 | template<typename X> | |
185 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(quaternion<X> const & rhs); | |
186 | ||
187 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(T const & rhs); | |
188 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(::std::complex<T> const & rhs); | |
189 | template<typename X> | |
190 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(quaternion<X> const & rhs); | |
191 | ||
192 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(T const & rhs); | |
193 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(::std::complex<T> const & rhs); | |
194 | template<typename X> | |
195 | quaternion<T>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(quaternion<X> const & rhs); | |
196 | }; | |
197 | ||
198 | } // namespace math | |
199 | } // namespace boost | |
200 | ||
201 | [endsect] | |
202 | ||
203 | [section:spec Quaternion Specializations] | |
204 | ||
205 | namespace boost{ namespace math{ | |
206 | ||
207 | template<> | |
208 | class quaternion<float> | |
209 | { | |
210 | public: | |
211 | typedef float ``[link math_toolkit.mem_typedef value_type]``; | |
212 | ||
213 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(float const & requested_a = 0.0f, float const & requested_b = 0.0f, float const & requested_c = 0.0f, float const & requested_d = 0.0f); | |
214 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(::std::complex<float> const & z0, ::std::complex<float> const & z1 = ::std::complex<float>()); | |
215 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<double> const & a_recopier); | |
216 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<long double> const & a_recopier); | |
217 | ||
218 | float ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts real]``() const; | |
219 | quaternion<float> ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts unreal]``() const; | |
220 | float ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_1]``() const; | |
221 | float ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_2]``() const; | |
222 | float ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_3]``() const; | |
223 | float ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_4]``() const; | |
224 | ::std::complex<float> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_1]``() const; | |
225 | ::std::complex<float> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_2]``() const; | |
226 | ||
227 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<float> const & a_affecter); | |
228 | template<typename X> | |
229 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<X> const & a_affecter); | |
230 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(float const & a_affecter); | |
231 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(::std::complex<float> const & a_affecter); | |
232 | ||
233 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(float const & rhs); | |
234 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(::std::complex<float> const & rhs); | |
235 | template<typename X> | |
236 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(quaternion<X> const & rhs); | |
237 | ||
238 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(float const & rhs); | |
239 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(::std::complex<float> const & rhs); | |
240 | template<typename X> | |
241 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(quaternion<X> const & rhs); | |
242 | ||
243 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(float const & rhs); | |
244 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(::std::complex<float> const & rhs); | |
245 | template<typename X> | |
246 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(quaternion<X> const & rhs); | |
247 | ||
248 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(float const & rhs); | |
249 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(::std::complex<float> const & rhs); | |
250 | template<typename X> | |
251 | quaternion<float>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(quaternion<X> const & rhs); | |
252 | }; | |
253 | ||
254 | [#math_quaternion_double] | |
255 | ||
256 | template<> | |
257 | class quaternion<double> | |
258 | { | |
259 | public: | |
260 | typedef double ``[link math_toolkit.mem_typedef value_type]``; | |
261 | ||
262 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(double const & requested_a = 0.0, double const & requested_b = 0.0, double const & requested_c = 0.0, double const & requested_d = 0.0); | |
263 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(::std::complex<double> const & z0, ::std::complex<double> const & z1 = ::std::complex<double>()); | |
264 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<float> const & a_recopier); | |
265 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<long double> const & a_recopier); | |
266 | ||
267 | double ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts real]``() const; | |
268 | quaternion<double> ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts unreal]``() const; | |
269 | double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_1]``() const; | |
270 | double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_2]``() const; | |
271 | double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_3]``() const; | |
272 | double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_4]``() const; | |
273 | ::std::complex<double> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_1]``() const; | |
274 | ::std::complex<double> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_2]``() const; | |
275 | ||
276 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<double> const & a_affecter); | |
277 | template<typename X> | |
278 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<X> const & a_affecter); | |
279 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(double const & a_affecter); | |
280 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(::std::complex<double> const & a_affecter); | |
281 | ||
282 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(double const & rhs); | |
283 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(::std::complex<double> const & rhs); | |
284 | template<typename X> | |
285 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(quaternion<X> const & rhs); | |
286 | ||
287 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(double const & rhs); | |
288 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(::std::complex<double> const & rhs); | |
289 | template<typename X> | |
290 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(quaternion<X> const & rhs); | |
291 | ||
292 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(double const & rhs); | |
293 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(::std::complex<double> const & rhs); | |
294 | template<typename X> | |
295 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(quaternion<X> const & rhs); | |
296 | ||
297 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(double const & rhs); | |
298 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(::std::complex<double> const & rhs); | |
299 | template<typename X> | |
300 | quaternion<double>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(quaternion<X> const & rhs); | |
301 | }; | |
302 | ||
303 | [#math_quaternion_long_double] | |
304 | ||
305 | template<> | |
306 | class quaternion<long double> | |
307 | { | |
308 | public: | |
309 | typedef long double ``[link math_toolkit.mem_typedef value_type]``; | |
310 | ||
311 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(long double const & requested_a = 0.0L, long double const & requested_b = 0.0L, long double const & requested_c = 0.0L, long double const & requested_d = 0.0L); | |
312 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(::std::complex<long double> const & z0, ::std::complex<long double> const & z1 = ::std::complex<long double>()); | |
313 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<float> const & a_recopier); | |
314 | explicit ``[link math_toolkit.quat_mem_fun.constructors quaternion]``(quaternion<double> const & a_recopier); | |
315 | ||
316 | long double ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts real]``() const; | |
317 | quaternion<long double> ``[link math_toolkit.quat_mem_fun.real_and_unreal_parts unreal]``() const; | |
318 | long double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_1]``() const; | |
319 | long double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_2]``() const; | |
320 | long double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_3]``() const; | |
321 | long double ``[link math_toolkit.quat_mem_fun.individual_real_components R_component_4]``() const; | |
322 | ::std::complex<long double> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_1]``() const; | |
323 | ::std::complex<long double> ``[link math_toolkit.quat_mem_fun.individual_complex_components C_component_2]``() const; | |
324 | ||
325 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<long double> const & a_affecter); | |
326 | template<typename X> | |
327 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(quaternion<X> const & a_affecter); | |
328 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(long double const & a_affecter); | |
329 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.assignment_operators operator = ]``(::std::complex<long double> const & a_affecter); | |
330 | ||
331 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(long double const & rhs); | |
332 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(::std::complex<long double> const & rhs); | |
333 | template<typename X> | |
334 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.addition_operators operator += ]``(quaternion<X> const & rhs); | |
335 | ||
336 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(long double const & rhs); | |
337 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(::std::complex<long double> const & rhs); | |
338 | template<typename X> | |
339 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.subtraction_operators operator -= ]``(quaternion<X> const & rhs); | |
340 | ||
341 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(long double const & rhs); | |
342 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(::std::complex<long double> const & rhs); | |
343 | template<typename X> | |
344 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.multiplication_operators operator *= ]``(quaternion<X> const & rhs); | |
345 | ||
346 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(long double const & rhs); | |
347 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(::std::complex<long double> const & rhs); | |
348 | template<typename X> | |
349 | quaternion<long double>& ``[link math_toolkit.quat_mem_fun.division_operators operator /= ]``(quaternion<X> const & rhs); | |
350 | }; | |
351 | ||
352 | } // namespace math | |
353 | } // namespace boost | |
354 | ||
355 | [endsect] | |
356 | ||
357 | [section:mem_typedef Quaternion Member Typedefs] | |
358 | ||
359 | [*value_type] | |
360 | ||
361 | Template version: | |
362 | ||
363 | typedef T value_type; | |
364 | ||
365 | Float specialization version: | |
366 | ||
367 | typedef float value_type; | |
368 | ||
369 | Double specialization version: | |
370 | ||
371 | typedef double value_type; | |
372 | ||
373 | Long double specialization version: | |
374 | ||
375 | typedef long double value_type; | |
376 | ||
377 | These provide easy acces to the type the template is built upon. | |
378 | ||
379 | [endsect] | |
380 | ||
381 | [section:quat_mem_fun Quaternion Member Functions] | |
382 | [h3 Constructors] | |
383 | ||
384 | Template version: | |
385 | ||
386 | explicit quaternion(T const & requested_a = T(), T const & requested_b = T(), T const & requested_c = T(), T const & requested_d = T()); | |
387 | explicit quaternion(::std::complex<T> const & z0, ::std::complex<T> const & z1 = ::std::complex<T>()); | |
388 | template<typename X> | |
389 | explicit quaternion(quaternion<X> const & a_recopier); | |
390 | ||
391 | Float specialization version: | |
392 | ||
393 | explicit quaternion(float const & requested_a = 0.0f, float const & requested_b = 0.0f, float const & requested_c = 0.0f, float const & requested_d = 0.0f); | |
394 | explicit quaternion(::std::complex<float> const & z0,::std::complex<float> const & z1 = ::std::complex<float>()); | |
395 | explicit quaternion(quaternion<double> const & a_recopier); | |
396 | explicit quaternion(quaternion<long double> const & a_recopier); | |
397 | ||
398 | Double specialization version: | |
399 | ||
400 | explicit quaternion(double const & requested_a = 0.0, double const & requested_b = 0.0, double const & requested_c = 0.0, double const & requested_d = 0.0); | |
401 | explicit quaternion(::std::complex<double> const & z0, ::std::complex<double> const & z1 = ::std::complex<double>()); | |
402 | explicit quaternion(quaternion<float> const & a_recopier); | |
403 | explicit quaternion(quaternion<long double> const & a_recopier); | |
404 | ||
405 | Long double specialization version: | |
406 | ||
407 | explicit quaternion(long double const & requested_a = 0.0L, long double const & requested_b = 0.0L, long double const & requested_c = 0.0L, long double const & requested_d = 0.0L); | |
408 | explicit quaternion( ::std::complex<long double> const & z0, ::std::complex<long double> const & z1 = ::std::complex<long double>()); | |
409 | explicit quaternion(quaternion<float> const & a_recopier); | |
410 | explicit quaternion(quaternion<double> const & a_recopier); | |
411 | ||
412 | A default constructor is provided for each form, which initializes | |
413 | each component to the default values for their type | |
414 | (i.e. zero for floating numbers). This constructor can also accept | |
415 | one to four base type arguments. A constructor is also provided to | |
416 | build quaternions from one or two complex numbers sharing the same | |
417 | base type. The unspecialized template also sports a templarized copy | |
418 | constructor, while the specialized forms have copy constructors | |
419 | from the other two specializations, which are explicit when a risk of | |
420 | precision loss exists. For the unspecialized form, the base type's | |
421 | constructors must not throw. | |
422 | ||
423 | Destructors and untemplated copy constructors (from the same type) are | |
424 | provided by the compiler. Converting copy constructors make use of a | |
425 | templated helper function in a "detail" subnamespace. | |
426 | ||
427 | [h3 Other member functions] | |
428 | [h4 Real and Unreal Parts] | |
429 | ||
430 | T real() const; | |
431 | quaternion<T> unreal() const; | |
432 | ||
433 | Like complex number, quaternions do have a meaningful notion of "real part", | |
434 | but unlike them there is no meaningful notion of "imaginary part". | |
435 | Instead there is an "unreal part" which itself is a quaternion, | |
436 | and usually nothing simpler (as opposed to the complex number case). | |
437 | These are returned by the first two functions. | |
438 | ||
439 | [h4 Individual Real Components] | |
440 | ||
441 | T R_component_1() const; | |
442 | T R_component_2() const; | |
443 | T R_component_3() const; | |
444 | T R_component_4() const; | |
445 | ||
446 | A quaternion having four real components, these are returned by these four | |
447 | functions. Hence real and R_component_1 return the same value. | |
448 | ||
449 | [h4 Individual Complex Components] | |
450 | ||
451 | ::std::complex<T> C_component_1() const; | |
452 | ::std::complex<T> C_component_2() const; | |
453 | ||
454 | A quaternion likewise has two complex components, and as we have seen above, | |
455 | for any quaternion __quat_formula we also have __quat_complex_formula. These functions return them. | |
456 | The real part of `q.C_component_1()` is the same as `q.real()`. | |
457 | ||
458 | [h3 Quaternion Member Operators] | |
459 | [h4 Assignment Operators] | |
460 | ||
461 | quaternion<T>& operator = (quaternion<T> const & a_affecter); | |
462 | template<typename X> | |
463 | quaternion<T>& operator = (quaternion<X> const& a_affecter); | |
464 | quaternion<T>& operator = (T const& a_affecter); | |
465 | quaternion<T>& operator = (::std::complex<T> const& a_affecter); | |
466 | ||
467 | These perform the expected assignment, with type modification if necessary | |
468 | (for instance, assigning from a base type will set the real part to that | |
469 | value, and all other components to zero). For the unspecialized form, | |
470 | the base type's assignment operators must not throw. | |
471 | ||
472 | [h4 Addition Operators] | |
473 | ||
474 | quaternion<T>& operator += (T const & rhs) | |
475 | quaternion<T>& operator += (::std::complex<T> const & rhs); | |
476 | template<typename X> | |
477 | quaternion<T>& operator += (quaternion<X> const & rhs); | |
478 | ||
479 | These perform the mathematical operation `(*this)+rhs` and store the result in | |
480 | `*this`. The unspecialized form has exception guards, which the specialized | |
481 | forms do not, so as to insure exception safety. For the unspecialized form, | |
482 | the base type's assignment operators must not throw. | |
483 | ||
484 | [h4 Subtraction Operators] | |
485 | ||
486 | quaternion<T>& operator -= (T const & rhs) | |
487 | quaternion<T>& operator -= (::std::complex<T> const & rhs); | |
488 | template<typename X> | |
489 | quaternion<T>& operator -= (quaternion<X> const & rhs); | |
490 | ||
491 | These perform the mathematical operation `(*this)-rhs` and store the result | |
492 | in `*this`. The unspecialized form has exception guards, which the | |
493 | specialized forms do not, so as to insure exception safety. | |
494 | For the unspecialized form, the base type's assignment operators | |
495 | must not throw. | |
496 | ||
497 | [h4 Multiplication Operators] | |
498 | ||
499 | quaternion<T>& operator *= (T const & rhs) | |
500 | quaternion<T>& operator *= (::std::complex<T> const & rhs); | |
501 | template<typename X> | |
502 | quaternion<T>& operator *= (quaternion<X> const & rhs); | |
503 | ||
504 | These perform the mathematical operation `(*this)*rhs` [*in this order] | |
505 | (order is important as multiplication is not commutative for quaternions) | |
506 | and store the result in `*this`. The unspecialized form has exception guards, | |
507 | which the specialized forms do not, so as to insure exception safety. | |
508 | For the unspecialized form, the base type's assignment operators must not throw. | |
509 | ||
510 | [h4 Division Operators] | |
511 | ||
512 | quaternion<T>& operator /= (T const & rhs) | |
513 | quaternion<T>& operator /= (::std::complex<T> const & rhs); | |
514 | template<typename X> | |
515 | quaternion<T>& operator /= (quaternion<X> const & rhs); | |
516 | ||
517 | These perform the mathematical operation `(*this)*inverse_of(rhs)` [*in this | |
518 | order] (order is important as multiplication is not commutative for quaternions) | |
519 | and store the result in `*this`. The unspecialized form has exception guards, | |
520 | which the specialized forms do not, so as to insure exception safety. | |
521 | For the unspecialized form, the base type's assignment operators must not throw. | |
522 | ||
523 | [endsect] | |
524 | [section:quat_non_mem Quaternion Non-Member Operators] | |
525 | ||
526 | [h4 Unary Plus] | |
527 | ||
528 | template<typename T> | |
529 | quaternion<T> operator + (quaternion<T> const & q); | |
530 | ||
531 | This unary operator simply returns q. | |
532 | ||
533 | [h4 Unary Minus] | |
534 | ||
535 | template<typename T> | |
536 | quaternion<T> operator - (quaternion<T> const & q); | |
537 | ||
538 | This unary operator returns the opposite of q. | |
539 | ||
540 | [h4 Binary Addition Operators] | |
541 | ||
542 | template<typename T> quaternion<T> operator + (T const & lhs, quaternion<T> const & rhs); | |
543 | template<typename T> quaternion<T> operator + (quaternion<T> const & lhs, T const & rhs); | |
544 | template<typename T> quaternion<T> operator + (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
545 | template<typename T> quaternion<T> operator + (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
546 | template<typename T> quaternion<T> operator + (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
547 | ||
548 | These operators return `quaternion<T>(lhs) += rhs`. | |
549 | ||
550 | [h4 Binary Subtraction Operators] | |
551 | ||
552 | template<typename T> quaternion<T> operator - (T const & lhs, quaternion<T> const & rhs); | |
553 | template<typename T> quaternion<T> operator - (quaternion<T> const & lhs, T const & rhs); | |
554 | template<typename T> quaternion<T> operator - (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
555 | template<typename T> quaternion<T> operator - (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
556 | template<typename T> quaternion<T> operator - (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
557 | ||
558 | These operators return `quaternion<T>(lhs) -= rhs`. | |
559 | ||
560 | [h4 Binary Multiplication Operators] | |
561 | ||
562 | template<typename T> quaternion<T> operator * (T const & lhs, quaternion<T> const & rhs); | |
563 | template<typename T> quaternion<T> operator * (quaternion<T> const & lhs, T const & rhs); | |
564 | template<typename T> quaternion<T> operator * (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
565 | template<typename T> quaternion<T> operator * (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
566 | template<typename T> quaternion<T> operator * (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
567 | ||
568 | These operators return `quaternion<T>(lhs) *= rhs`. | |
569 | ||
570 | [h4 Binary Division Operators] | |
571 | ||
572 | template<typename T> quaternion<T> operator / (T const & lhs, quaternion<T> const & rhs); | |
573 | template<typename T> quaternion<T> operator / (quaternion<T> const & lhs, T const & rhs); | |
574 | template<typename T> quaternion<T> operator / (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
575 | template<typename T> quaternion<T> operator / (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
576 | template<typename T> quaternion<T> operator / (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
577 | ||
578 | These operators return `quaternion<T>(lhs) /= rhs`. It is of course still an | |
579 | error to divide by zero... | |
580 | ||
581 | [h4 Equality Operators] | |
582 | ||
583 | template<typename T> bool operator == (T const & lhs, quaternion<T> const & rhs); | |
584 | template<typename T> bool operator == (quaternion<T> const & lhs, T const & rhs); | |
585 | template<typename T> bool operator == (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
586 | template<typename T> bool operator == (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
587 | template<typename T> bool operator == (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
588 | ||
589 | These return true if and only if the four components of `quaternion<T>(lhs)` | |
590 | are equal to their counterparts in `quaternion<T>(rhs)`. As with any | |
591 | floating-type entity, this is essentially meaningless. | |
592 | ||
593 | [h4 Inequality Operators] | |
594 | ||
595 | template<typename T> bool operator != (T const & lhs, quaternion<T> const & rhs); | |
596 | template<typename T> bool operator != (quaternion<T> const & lhs, T const & rhs); | |
597 | template<typename T> bool operator != (::std::complex<T> const & lhs, quaternion<T> const & rhs); | |
598 | template<typename T> bool operator != (quaternion<T> const & lhs, ::std::complex<T> const & rhs); | |
599 | template<typename T> bool operator != (quaternion<T> const & lhs, quaternion<T> const & rhs); | |
600 | ||
601 | These return true if and only if `quaternion<T>(lhs) == quaternion<T>(rhs)` is | |
602 | false. As with any floating-type entity, this is essentially meaningless. | |
603 | ||
604 | [h4 Stream Extractor] | |
605 | ||
606 | template<typename T, typename charT, class traits> | |
607 | ::std::basic_istream<charT,traits>& operator >> (::std::basic_istream<charT,traits> & is, quaternion<T> & q); | |
608 | ||
609 | Extracts a quaternion q of one of the following forms | |
610 | (with a, b, c and d of type `T`): | |
611 | ||
612 | [^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))] | |
613 | ||
614 | The input values must be convertible to `T`. If bad input is encountered, | |
615 | calls `is.setstate(ios::failbit)` (which may throw ios::failure (27.4.5.3)). | |
616 | ||
617 | [*Returns:] `is`. | |
618 | ||
619 | The rationale for the list of accepted formats is that either we have a | |
620 | list of up to four reals, or else we have a couple of complex numbers, | |
621 | and in that case if it formated as a proper complex number, then it should | |
622 | be accepted. Thus potential ambiguities are lifted (for instance (a,b) is | |
623 | (a,b,0,0) and not (a,0,b,0), i.e. it is parsed as a list of two real numbers | |
624 | and not two complex numbers which happen to have imaginary parts equal to zero). | |
625 | ||
626 | [h4 Stream Inserter] | |
627 | ||
628 | template<typename T, typename charT, class traits> | |
629 | ::std::basic_ostream<charT,traits>& operator << (::std::basic_ostream<charT,traits> & os, quaternion<T> const & q); | |
630 | ||
631 | Inserts the quaternion q onto the stream `os` as if it were implemented as follows: | |
632 | ||
633 | template<typename T, typename charT, class traits> | |
634 | ::std::basic_ostream<charT,traits>& operator << ( | |
635 | ::std::basic_ostream<charT,traits> & os, | |
636 | quaternion<T> const & q) | |
637 | { | |
638 | ::std::basic_ostringstream<charT,traits> s; | |
639 | ||
640 | s.flags(os.flags()); | |
641 | s.imbue(os.getloc()); | |
642 | s.precision(os.precision()); | |
643 | ||
644 | s << '(' << q.R_component_1() << ',' | |
645 | << q.R_component_2() << ',' | |
646 | << q.R_component_3() << ',' | |
647 | << q.R_component_4() << ')'; | |
648 | ||
649 | return os << s.str(); | |
650 | } | |
651 | ||
652 | [endsect] | |
653 | ||
654 | [section:value_op Quaternion Value Operations] | |
655 | ||
656 | [h4 real and unreal] | |
657 | ||
658 | template<typename T> T real(quaternion<T> const & q); | |
659 | template<typename T> quaternion<T> unreal(quaternion<T> const & q); | |
660 | ||
661 | These return `q.real()` and `q.unreal()` respectively. | |
662 | ||
663 | [h4 conj] | |
664 | ||
665 | template<typename T> quaternion<T> conj(quaternion<T> const & q); | |
666 | ||
667 | This returns the conjugate of the quaternion. | |
668 | ||
669 | [h4 sup] | |
670 | ||
671 | template<typename T> T sup(quaternion<T> const & q); | |
672 | ||
673 | This return the sup norm (the greatest among | |
674 | `abs(q.R_component_1())...abs(q.R_component_4()))` of the quaternion. | |
675 | ||
676 | [h4 l1] | |
677 | ||
678 | template<typename T> T l1(quaternion<T> const & q); | |
679 | ||
680 | This return the l1 norm `(abs(q.R_component_1())+...+abs(q.R_component_4()))` | |
681 | of the quaternion. | |
682 | ||
683 | [h4 abs] | |
684 | ||
685 | template<typename T> T abs(quaternion<T> const & q); | |
686 | ||
687 | This return the magnitude (Euclidian norm) of the quaternion. | |
688 | ||
689 | [h4 norm] | |
690 | ||
691 | template<typename T> T norm(quaternion<T>const & q); | |
692 | ||
693 | This return the (Cayley) norm of the quaternion. | |
694 | The term "norm" might be confusing, as most people associate it with the | |
695 | Euclidian norm (and quadratic functionals). For this version of | |
696 | (the mathematical objects known as) quaternions, the Euclidian norm | |
697 | (also known as magnitude) is the square root of the Cayley norm. | |
698 | ||
699 | [endsect] | |
700 | ||
701 | [section:create Quaternion Creation Functions] | |
702 | ||
703 | template<typename T> quaternion<T> spherical(T const & rho, T const & theta, T const & phi1, T const & phi2); | |
704 | template<typename T> quaternion<T> semipolar(T const & rho, T const & alpha, T const & theta1, T const & theta2); | |
705 | template<typename T> quaternion<T> multipolar(T const & rho1, T const & theta1, T const & rho2, T const & theta2); | |
706 | template<typename T> quaternion<T> cylindrospherical(T const & t, T const & radius, T const & longitude, T const & latitude); | |
707 | template<typename T> quaternion<T> cylindrical(T const & r, T const & angle, T const & h1, T const & h2); | |
708 | ||
709 | These build quaternions in a way similar to the way polar builds complex | |
710 | numbers, as there is no strict equivalent to polar coordinates for quaternions. | |
711 | ||
712 | [#math_quaternions.creation_spherical] `spherical` is a simple transposition of `polar`, it takes as inputs | |
713 | a (positive) magnitude and a point on the hypersphere, given by three angles. | |
714 | The first of these, `theta` has a natural range of `-pi` to `+pi`, and the other | |
715 | two have natural ranges of `-pi/2` to `+pi/2` (as is the case with the usual | |
716 | spherical coordinates in __R3). Due to the many symmetries and periodicities, | |
717 | nothing untoward happens if the magnitude is negative or the angles are | |
718 | outside their natural ranges. The expected degeneracies (a magnitude of | |
719 | zero ignores the angles settings...) do happen however. | |
720 | ||
721 | [#math_quaternions.creation_cylindrical] `cylindrical` is likewise a simple transposition of the usual | |
722 | cylindrical coordinates in __R3, which in turn is another derivative of | |
723 | planar polar coordinates. The first two inputs are the polar coordinates of | |
724 | the first __C component of the quaternion. The third and fourth inputs | |
725 | are placed into the third and fourth __R components of the quaternion, | |
726 | respectively. | |
727 | ||
728 | [#math_quaternions.creation_multipolar] `multipolar` is yet another simple generalization of polar coordinates. | |
729 | This time, both __C components of the quaternion are given in polar coordinates. | |
730 | ||
731 | [#math_quaternions.creation_cylindrospherical] `cylindrospherical` is specific to quaternions. It is often interesting to | |
732 | consider __H as the cartesian product of __R by __R3 (the quaternionic | |
733 | multiplication as then a special form, as given here). This function | |
734 | therefore builds a quaternion from this representation, with the __R3 | |
735 | component given in usual __R3 spherical coordinates. | |
736 | ||
737 | [#math_quaternions.creation_semipolar] `semipolar` is another generator which is specific to quaternions. | |
738 | It takes as a first input the magnitude of the quaternion, as a | |
739 | second input an angle in the range `0` to `+pi/2` such that magnitudes | |
740 | of the first two __C components of the quaternion are the product of the | |
741 | first input and the sine and cosine of this angle, respectively, and finally | |
742 | as third and fourth inputs angles in the range `-pi/2` to `+pi/2` which | |
743 | represent the arguments of the first and second __C components of | |
744 | the quaternion, respectively. As usual, nothing untoward happens if | |
745 | what should be magnitudes are negative numbers or angles are out of their | |
746 | natural ranges, as symmetries and periodicities kick in. | |
747 | ||
748 | In this version of our implementation of quaternions, there is no | |
749 | analogue of the complex value operation `arg` as the situation is | |
750 | somewhat more complicated. Unit quaternions are linked both to | |
751 | rotations in __R3 and in __R4, and the correspondences are not too complicated, | |
752 | but there is currently a lack of standard (de facto or de jure) matrix | |
753 | library with which the conversions could work. This should be remedied in | |
754 | a further revision. In the mean time, an example of how this could be | |
755 | done is presented here for | |
756 | [@../../example/HSO3.hpp __R3], and here for | |
757 | [@../../example/HSO4.hpp __R4] | |
758 | ([@../../example/HSO3SO4.cpp example test file]). | |
759 | ||
760 | [endsect] | |
761 | ||
762 | [section:trans Quaternion Transcendentals] | |
763 | ||
764 | There is no `log` or `sqrt` provided for quaternions in this implementation, | |
765 | and `pow` is likewise restricted to integral powers of the exponent. | |
766 | There are several reasons to this: on the one hand, the equivalent of | |
767 | analytic continuation for quaternions ("branch cuts") remains to be | |
768 | investigated thoroughly (by me, at any rate...), and we wish to avoid the | |
769 | nonsense introduced in the standard by exponentiations of complexes by | |
770 | complexes (which is well defined, but not in the standard...). | |
771 | Talking of nonsense, saying that `pow(0,0)` is "implementation defined" is just | |
772 | plain brain-dead... | |
773 | ||
774 | We do, however provide several transcendentals, chief among which is the | |
775 | exponential. This author claims the complete proof of the "closed formula" | |
776 | as his own, as well as its independant invention (there are claims to prior | |
777 | invention of the formula, such as one by Professor Shoemake, and it is | |
778 | possible that the formula had been known a couple of centuries back, but in | |
779 | absence of bibliographical reference, the matter is pending, awaiting further | |
780 | investigation; on the other hand, the definition and existence of the | |
781 | exponential on the quaternions, is of course a fact known for a very long time). | |
782 | Basically, any converging power series with real coefficients which allows for a | |
783 | closed formula in __C can be transposed to __H. More transcendentals of this | |
784 | type could be added in a further revision upon request. It should be | |
785 | noted that it is these functions which force the dependency upon the | |
786 | [@../../../../boost/math/special_functions/sinc.hpp boost/math/special_functions/sinc.hpp] and the | |
787 | [@../../../../boost/math/special_functions/sinhc.hpp boost/math/special_functions/sinhc.hpp] headers. | |
788 | ||
789 | [h4 exp] | |
790 | ||
791 | template<typename T> quaternion<T> exp(quaternion<T> const & q); | |
792 | ||
793 | Computes the exponential of the quaternion. | |
794 | ||
795 | [h4 cos] | |
796 | ||
797 | template<typename T> quaternion<T> cos(quaternion<T> const & q); | |
798 | ||
799 | Computes the cosine of the quaternion | |
800 | ||
801 | [h4 sin] | |
802 | ||
803 | template<typename T> quaternion<T> sin(quaternion<T> const & q); | |
804 | ||
805 | Computes the sine of the quaternion. | |
806 | ||
807 | [h4 tan] | |
808 | ||
809 | template<typename T> quaternion<T> tan(quaternion<T> const & q); | |
810 | ||
811 | Computes the tangent of the quaternion. | |
812 | ||
813 | [h4 cosh] | |
814 | ||
815 | template<typename T> quaternion<T> cosh(quaternion<T> const & q); | |
816 | ||
817 | Computes the hyperbolic cosine of the quaternion. | |
818 | ||
819 | [h4 sinh] | |
820 | ||
821 | template<typename T> quaternion<T> sinh(quaternion<T> const & q); | |
822 | ||
823 | Computes the hyperbolic sine of the quaternion. | |
824 | ||
825 | [h4 tanh] | |
826 | ||
827 | template<typename T> quaternion<T> tanh(quaternion<T> const & q); | |
828 | ||
829 | Computes the hyperbolic tangent of the quaternion. | |
830 | ||
831 | [h4 pow] | |
832 | ||
833 | template<typename T> quaternion<T> pow(quaternion<T> const & q, int n); | |
834 | ||
835 | Computes the n-th power of the quaternion q. | |
836 | ||
837 | [endsect] | |
838 | ||
839 | [section:quat_tests Test Program] | |
840 | ||
841 | The [@../../test/quaternion_test.cpp quaternion_test.cpp] | |
842 | test program tests quaternions specializations for float, double and long double | |
843 | ([@../quaternion/output.txt sample output], with message output | |
844 | enabled). | |
845 | ||
846 | If you define the symbol TEST_VERBOSE, you will get | |
847 | additional output ([@../quaternion/output_more.txt verbose output]); | |
848 | this will only be helpfull if you enable message output at the same time, | |
849 | of course (by uncommenting the relevant line in the test or by adding | |
850 | [^--log_level=messages] to your command line,...). In that case, and if you | |
851 | are running interactively, you may in addition define the symbol | |
852 | BOOST_INTERACTIVE_TEST_INPUT_ITERATOR to interactively test the input | |
853 | operator with input of your choice from the standard input | |
854 | (instead of hard-coding it in the test). | |
855 | ||
856 | [endsect] | |
857 | ||
858 | [section:exp The Quaternionic Exponential] | |
859 | ||
860 | Please refer to the following PDF's: | |
861 | ||
862 | *[@../quaternion/TQE.pdf The Quaternionic Exponential (and beyond)] | |
863 | *[@../quaternion/TQE_EA.pdf The Quaternionic Exponential (and beyond) ERRATA & ADDENDA] | |
864 | ||
865 | [endsect] | |
866 | ||
867 | [section:acknowledgement Acknowledgements] | |
868 | ||
869 | The mathematical text has been typeset with | |
870 | [@http://www.nisus-soft.com/ Nisus Writer]. Jens Maurer has helped with | |
871 | portability and standard adherence, and was the Review Manager | |
872 | for this library. More acknowledgements in the History section. | |
873 | Thank you to all who contributed to the discution about this library. | |
874 | ||
875 | [endsect] | |
876 | ||
877 | [section:quat_history History] | |
878 | ||
879 | * 1.5.9 - 13/5/2013: Incorporated into Boost.Math. | |
880 | * 1.5.8 - 17/12/2005: Converted documentation to Quickbook Format. | |
881 | * 1.5.7 - 24/02/2003: transitionned to the unit test framework; <boost/config.hpp> now included by the library header (rather than the test files). | |
882 | * 1.5.6 - 15/10/2002: Gcc2.95.x and stlport on linux compatibility by Alkis Evlogimenos (alkis@routescience.com). | |
883 | * 1.5.5 - 27/09/2002: Microsoft VCPP 7 compatibility, by Michael Stevens (michael@acfr.usyd.edu.au); requires the /Za compiler option. | |
884 | * 1.5.4 - 19/09/2002: fixed problem with multiple inclusion (in different translation units); attempt at an improved compatibility with Microsoft compilers, by Michael Stevens (michael@acfr.usyd.edu.au) and Fredrik Blomqvist; other compatibility fixes. | |
885 | * 1.5.3 - 01/02/2002: bugfix and Gcc 2.95.3 compatibility by Douglas Gregor (gregod@cs.rpi.edu). | |
886 | * 1.5.2 - 07/07/2001: introduced namespace math. | |
887 | * 1.5.1 - 07/06/2001: (end of Boost review) now includes <boost/math/special_functions/sinc.hpp> and <boost/math/special_functions/sinhc.hpp> instead of <boost/special_functions.hpp>; corrected bug in sin (Daryle Walker); removed check for self-assignment (Gary Powel); made converting functions explicit (Gary Powel); added overflow guards for division operators and abs (Peter Schmitteckert); added sup and l1; used Vesa Karvonen's CPP metaprograming technique to simplify code. | |
888 | * 1.5.0 - 26/03/2001: boostification, inlining of all operators except input, output and pow, fixed exception safety of some members (template version) and output operator, added spherical, semipolar, multipolar, cylindrospherical and cylindrical. | |
889 | * 1.4.0 - 09/01/2001: added tan and tanh. | |
890 | * 1.3.1 - 08/01/2001: cosmetic fixes. | |
891 | * 1.3.0 - 12/07/2000: pow now uses Maarten Hilferink's (mhilferink@tip.nl) algorithm. | |
892 | * 1.2.0 - 25/05/2000: fixed the division operators and output; changed many signatures. | |
893 | * 1.1.0 - 23/05/2000: changed sinc into sinc_pi; added sin, cos, sinh, cosh. | |
894 | * 1.0.0 - 10/08/1999: first public version. | |
895 | ||
896 | [endsect] | |
897 | [section:quat_todo To Do] | |
898 | ||
899 | * Improve testing. | |
900 | * Rewrite input operatore using Spirit (creates a dependency). | |
901 | * Put in place an Expression Template mechanism (perhaps borrowing from uBlas). | |
902 | * Use uBlas for the link with rotations (and move from the | |
903 | [@../../example/HSO3SO4.cpp example] | |
904 | implementation to an efficient one). | |
905 | ||
906 | [endsect] | |
907 | [endmathpart] | |
908 | ||
909 | [/ | |
910 | Copyright 1999, 2005, 2013 Hubert Holin. | |
911 | Distributed under the Boost Software License, Version 1.0. | |
912 | (See accompanying file LICENSE_1_0.txt or copy at | |
913 | http://www.boost.org/LICENSE_1_0.txt). | |
914 | ] | |
915 | ||
916 | ||
917 | ||
918 |