blob: a2e3e91bd1be7271f407e7c430524cf40b1ef13f [file] [log] [blame]
Brian Silvermana8ce4c32018-08-04 23:57:09 -07001// 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
17Demonstrate interoperability with Boost.Quaternion.
18
19Output:
20@verbatim
21
22//[quaternion_output_1
23+L = (4,3,2,1) m
24-L = (-4,-3,-2,-1) m
25L+L = (8,6,4,2) m
26L-L = (0,0,0,0) m
27L*L = (2,24,16,8) m^2
28L/L = (1,0,0,0) dimensionless
29L^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)
35L+L = (8 m,6 m,4 m,2 m)
36L-L = (0 m,0 m,0 m,0 m)
37L^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
58BOOST_TYPEOF_REGISTER_TEMPLATE(boost::math::quaternion, 1)
59
60#endif
61
62namespace boost {
63
64namespace units {
65
66//[quaternion_class_snippet_1a
67/// specialize power typeof helper
68template<class Y,long N,long D>
69struct 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
78 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
87template<class Y,long N,long D>
88struct 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
97 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> >
106template<class Unit,long N,long D,class Y>
107struct 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
124 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> >
143template<class Unit,long N,long D,class Y>
144struct 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
161 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
182int 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}