quaternion.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. \file
  12. \brief quaternion.cpp
  13. \details
  14. Demonstrate interoperability with Boost.Quaternion.
  15. Output:
  16. @verbatim
  17. //[quaternion_output_1
  18. +L = (4,3,2,1) m
  19. -L = (-4,-3,-2,-1) m
  20. L+L = (8,6,4,2) m
  21. L-L = (0,0,0,0) m
  22. L*L = (2,24,16,8) m^2
  23. L/L = (1,0,0,0) dimensionless
  24. L^3 = (-104,102,68,34) m^3
  25. //]
  26. //[quaternion_output_2
  27. +L = (4 m,3 m,2 m,1 m)
  28. -L = (-4 m,-3 m,-2 m,-1 m)
  29. L+L = (8 m,6 m,4 m,2 m)
  30. L-L = (0 m,0 m,0 m,0 m)
  31. L^3 = (-104 m^3,102 m^3,68 m^3,34 m^3)
  32. //]
  33. @endverbatim
  34. **/
  35. #include <iostream>
  36. #include <boost/math/quaternion.hpp>
  37. #include <boost/mpl/list.hpp>
  38. #include <boost/units/pow.hpp>
  39. #include <boost/units/quantity.hpp>
  40. #include <boost/units/io.hpp>
  41. #include "test_system.hpp"
  42. #if BOOST_UNITS_HAS_BOOST_TYPEOF
  43. #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
  44. BOOST_TYPEOF_REGISTER_TEMPLATE(boost::math::quaternion, 1)
  45. #endif
  46. namespace boost {
  47. namespace units {
  48. //[quaternion_class_snippet_1a
  49. /// specialize power typeof helper
  50. template<class Y,long N,long D>
  51. struct power_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
  52. {
  53. // boost::math::quaternion only supports integer powers
  54. BOOST_STATIC_ASSERT(D==1);
  55. typedef boost::math::quaternion<
  56. typename power_typeof_helper<Y,static_rational<N,D> >::type
  57. > type;
  58. static type value(const boost::math::quaternion<Y>& x)
  59. {
  60. return boost::math::pow(x,static_cast<int>(N));
  61. }
  62. };
  63. //]
  64. //[quaternion_class_snippet_1b
  65. /// specialize root typeof helper
  66. template<class Y,long N,long D>
  67. struct root_typeof_helper<boost::math::quaternion<Y>,static_rational<N,D> >
  68. {
  69. // boost::math::quaternion only supports integer powers
  70. BOOST_STATIC_ASSERT(N==1);
  71. typedef boost::math::quaternion<
  72. typename root_typeof_helper<Y,static_rational<N,D> >::type
  73. > type;
  74. static type value(const boost::math::quaternion<Y>& x)
  75. {
  76. return boost::math::pow(x,static_cast<int>(D));
  77. }
  78. };
  79. //]
  80. //[quaternion_class_snippet_2a
  81. /// specialize power typeof helper for quaternion<quantity<Unit,Y> >
  82. template<class Unit,long N,long D,class Y>
  83. struct power_typeof_helper<
  84. boost::math::quaternion<quantity<Unit,Y> >,
  85. static_rational<N,D> >
  86. {
  87. typedef typename power_typeof_helper<
  88. Y,
  89. static_rational<N,D>
  90. >::type value_type;
  91. typedef typename power_typeof_helper<
  92. Unit,
  93. static_rational<N,D>
  94. >::type unit_type;
  95. typedef quantity<unit_type,value_type> quantity_type;
  96. typedef boost::math::quaternion<quantity_type> type;
  97. static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)
  98. {
  99. const boost::math::quaternion<value_type> tmp =
  100. pow<static_rational<N,D> >(boost::math::quaternion<Y>(
  101. x.R_component_1().value(),
  102. x.R_component_2().value(),
  103. x.R_component_3().value(),
  104. x.R_component_4().value()));
  105. return type(quantity_type::from_value(tmp.R_component_1()),
  106. quantity_type::from_value(tmp.R_component_2()),
  107. quantity_type::from_value(tmp.R_component_3()),
  108. quantity_type::from_value(tmp.R_component_4()));
  109. }
  110. };
  111. //]
  112. //[quaternion_class_snippet_2b
  113. /// specialize root typeof helper for quaternion<quantity<Unit,Y> >
  114. template<class Unit,long N,long D,class Y>
  115. struct root_typeof_helper<
  116. boost::math::quaternion<quantity<Unit,Y> >,
  117. static_rational<N,D> >
  118. {
  119. typedef typename root_typeof_helper<
  120. Y,
  121. static_rational<N,D>
  122. >::type value_type;
  123. typedef typename root_typeof_helper<
  124. Unit,
  125. static_rational<N,D>
  126. >::type unit_type;
  127. typedef quantity<unit_type,value_type> quantity_type;
  128. typedef boost::math::quaternion<quantity_type> type;
  129. static type value(const boost::math::quaternion<quantity<Unit,Y> >& x)
  130. {
  131. const boost::math::quaternion<value_type> tmp =
  132. root<static_rational<N,D> >(boost::math::quaternion<Y>(
  133. x.R_component_1().value(),
  134. x.R_component_2().value(),
  135. x.R_component_3().value(),
  136. x.R_component_4().value()));
  137. return type(quantity_type::from_value(tmp.R_component_1()),
  138. quantity_type::from_value(tmp.R_component_2()),
  139. quantity_type::from_value(tmp.R_component_3()),
  140. quantity_type::from_value(tmp.R_component_4()));
  141. }
  142. };
  143. //]
  144. } // namespace units
  145. } // namespace boost
  146. int main(void)
  147. {
  148. using boost::math::quaternion;
  149. using namespace boost::units;
  150. using namespace boost::units::test;
  151. using boost::units::pow;
  152. {
  153. //[quaternion_snippet_1
  154. typedef quantity<length,quaternion<double> > length_dimension;
  155. length_dimension L(quaternion<double>(4.0,3.0,2.0,1.0)*meters);
  156. //]
  157. std::cout << "+L = " << +L << std::endl
  158. << "-L = " << -L << std::endl
  159. << "L+L = " << L+L << std::endl
  160. << "L-L = " << L-L << std::endl
  161. << "L*L = " << L*L << std::endl
  162. << "L/L = " << L/L << std::endl
  163. // unfortunately, without qualification msvc still
  164. // finds boost::math::pow by ADL.
  165. << "L^3 = " << boost::units::pow<3>(L) << std::endl
  166. // << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
  167. // << "3vL = " << root<3>(L) << std::endl
  168. // << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
  169. << std::endl;
  170. }
  171. {
  172. //[quaternion_snippet_2
  173. typedef quaternion<quantity<length> > length_dimension;
  174. length_dimension L(4.0*meters,3.0*meters,2.0*meters,1.0*meters);
  175. //]
  176. std::cout << "+L = " << +L << std::endl
  177. << "-L = " << -L << std::endl
  178. << "L+L = " << L+L << std::endl
  179. << "L-L = " << L-L << std::endl
  180. // << "L*L = " << L*L << std::endl
  181. // << "L/L = " << L/L << std::endl
  182. << "L^3 = " << boost::units::pow<3>(L) << std::endl
  183. // << "L^(3/2) = " << pow< static_rational<3,2> >(L) << std::endl
  184. // << "3vL = " << root<3>(L) << std::endl
  185. // << "(3/2)vL = " << root< static_rational<3,2> >(L) << std::endl
  186. << std::endl;
  187. }
  188. return 0;
  189. }