1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
2 // unit/quantity manipulation and conversion
3 //
4 // Copyright (C) 2003-2008 Matthias Christian Schabel
5 // Copyright (C) 2007-2008 Steven Watanabe
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10
11 /**
12 \file
13
14 \brief quaternion.cpp
15
16 \details
17 Demonstrate interoperability with Boost.Quaternion.
18
19 Output:
20 @verbatim
21
22 //[quaternion_output_1
23 +L = (4,3,2,1) m
24 -L = (-4,-3,-2,-1) m
25 L+L = (8,6,4,2) m
26 L-L = (0,0,0,0) m
27 L*L = (2,24,16,8) m^2
28 L/L = (1,0,0,0) dimensionless
29 L^3 = (-104,102,68,34) m^3
30 //]
31
32 //[quaternion_output_2
33 +L = (4 m,3 m,2 m,1 m)
34 -L = (-4 m,-3 m,-2 m,-1 m)
35 L+L = (8 m,6 m,4 m,2 m)
36 L-L = (0 m,0 m,0 m,0 m)
37 L^3 = (-104 m^3,102 m^3,68 m^3,34 m^3)
38 //]
39
40 @endverbatim
41 **/
42
43 #include <iostream>
44
45 #include <boost/math/quaternion.hpp>
46 #include <boost/mpl/list.hpp>
47
48 #include <boost/units/pow.hpp>
49 #include <boost/units/quantity.hpp>
50 #include <boost/units/io.hpp>
51
52 #include "test_system.hpp"
53
54 #if BOOST_UNITS_HAS_BOOST_TYPEOF
55
56 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
57
58 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::math::quaternion, 1)
59
60 #endif
61
62 namespace boost {
63
64 namespace units {
65
66 //[quaternion_class_snippet_1a
67 /// specialize power typeof helper
68 template<class Y,long N,long D>
69 struct power_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
70 {
71 // boost::math::quaternion only supports integer powers
72 BOOST_STATIC_ASSERT(D==1);
73
74 typedef boost::math::quaternion<
75 typename power_typeof_helper<Y,static_rational<N,D> >::type
76 > type;
77
valueboost::units::power_typeof_helper78 static type value(const boost::math::quaternion<Y>& x)
79 {
80 return boost::math::pow(x,static_cast<int>(N));
81 }
82 };
83 //]
84
85 //[quaternion_class_snippet_1b
86 /// specialize root typeof helper
87 template<class Y,long N,long D>
88 struct root_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
89 {
90 // boost::math::quaternion only supports integer powers
91 BOOST_STATIC_ASSERT(N==1);
92
93 typedef boost::math::quaternion<
94 typename root_typeof_helper<Y,static_rational<N,D> >::type
95 > type;
96
valueboost::units::root_typeof_helper97 static type value(const boost::math::quaternion<Y>& x)
98 {
99 return boost::math::pow(x,static_cast<int>(D));
100 }
101 };
102 //]
103
104 //[quaternion_class_snippet_2a
105 /// specialize power typeof helper for quaternion<quantity<Unit,Y> >
106 template<class Unit,long N,long D,class Y>
107 struct power_typeof_helper<
108 boost::math::quaternion<quantity<Unit,Y> >,
109 static_rational<N,D> >
110 {
111 typedef typename power_typeof_helper<
112 Y,
113 static_rational<N,D>
114 >::type value_type;
115
116 typedef typename power_typeof_helper<
117 Unit,
118 static_rational<N,D>
119 >::type unit_type;
120
121 typedef quantity<unit_type,value_type> quantity_type;
122 typedef boost::math::quaternion<quantity_type> type;
123
valueboost::units::power_typeof_helper124 static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)
125 {
126 const boost::math::quaternion<value_type> tmp =
127 pow<static_rational<N,D> >(boost::math::quaternion<Y>(
128 x.R_component_1().value(),
129 x.R_component_2().value(),
130 x.R_component_3().value(),
131 x.R_component_4().value()));
132
133 return type(quantity_type::from_value(tmp.R_component_1()),
134 quantity_type::from_value(tmp.R_component_2()),
135 quantity_type::from_value(tmp.R_component_3()),
136 quantity_type::from_value(tmp.R_component_4()));
137 }
138 };
139 //]
140
141 //[quaternion_class_snippet_2b
142 /// specialize root typeof helper for quaternion<quantity<Unit,Y> >
143 template<class Unit,long N,long D,class Y>
144 struct root_typeof_helper<
145 boost::math::quaternion<quantity<Unit,Y> >,
146 static_rational<N,D> >
147 {
148 typedef typename root_typeof_helper<
149 Y,
150 static_rational<N,D>
151 >::type value_type;
152
153 typedef typename root_typeof_helper<
154 Unit,
155 static_rational<N,D>
156 >::type unit_type;
157
158 typedef quantity<unit_type,value_type> quantity_type;
159 typedef boost::math::quaternion<quantity_type> type;
160
valueboost::units::root_typeof_helper161 static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)
162 {
163 const boost::math::quaternion<value_type> tmp =
164 root<static_rational<N,D> >(boost::math::quaternion<Y>(
165 x.R_component_1().value(),
166 x.R_component_2().value(),
167 x.R_component_3().value(),
168 x.R_component_4().value()));
169
170 return type(quantity_type::from_value(tmp.R_component_1()),
171 quantity_type::from_value(tmp.R_component_2()),
172 quantity_type::from_value(tmp.R_component_3()),
173 quantity_type::from_value(tmp.R_component_4()));
174 }
175 };
176 //]
177
178 } // namespace units
179
180 } // namespace boost
181
main(void)182 int main(void)
183 {
184 using boost::math::quaternion;
185 using namespace boost::units;
186 using namespace boost::units::test;
187 using boost::units::pow;
188
189 {
190 //[quaternion_snippet_1
191 typedef quantity<length,quaternion<double> > length_dimension;
192
193 length_dimension L(quaternion<double>(4.0,3.0,2.0,1.0)*meters);
194 //]
195
196 std::cout << "+L = " << +L << std::endl
197 << "-L = " << -L << std::endl
198 << "L+L = " << L+L << std::endl
199 << "L-L = " << L-L << std::endl
200 << "L*L = " << L*L << std::endl
201 << "L/L = " << L/L << std::endl
202 // unfortunately, without qualification msvc still
203 // finds boost::math::pow by ADL.
204 << "L^3 = " << boost::units::pow<3>(L) << std::endl
205 // << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
206 // << "3vL = " << root<3>(L) << std::endl
207 // << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
208 << std::endl;
209 }
210
211 {
212 //[quaternion_snippet_2
213 typedef quaternion<quantity<length> > length_dimension;
214
215 length_dimension L(4.0*meters,3.0*meters,2.0*meters,1.0*meters);
216 //]
217
218 std::cout << "+L = " << +L << std::endl
219 << "-L = " << -L << std::endl
220 << "L+L = " << L+L << std::endl
221 << "L-L = " << L-L << std::endl
222 // << "L*L = " << L*L << std::endl
223 // << "L/L = " << L/L << std::endl
224 << "L^3 = " << boost::units::pow<3>(L) << std::endl
225 // << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
226 // << "3vL = " << root<3>(L) << std::endl
227 // << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
228 << std::endl;
229 }
230
231 return 0;
232 }
233