HSO3SO4.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. // test file for HSO3.hpp and HSO4.hpp
  2. // (C) Copyright Hubert Holin 2001.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. #include <iostream>
  7. #include <boost/math/quaternion.hpp>
  8. #include "HSO3.hpp"
  9. #include "HSO4.hpp"
  10. const int number_of_intervals = 5;
  11. const float pi = ::std::atan(1.0f)*4;
  12. void test_SO3();
  13. void test_SO4();
  14. int main()
  15. {
  16. test_SO3();
  17. test_SO4();
  18. ::std::cout << "That's all folks!" << ::std::endl;
  19. }
  20. //
  21. // Test of quaternion and R^3 rotation relationship
  22. //
  23. void test_SO3_spherical()
  24. {
  25. ::std::cout << "Testing spherical:" << ::std::endl;
  26. ::std::cout << ::std::endl;
  27. const float rho = 1.0f;
  28. float theta;
  29. float phi1;
  30. float phi2;
  31. for (int idxphi2 = 0; idxphi2 <= number_of_intervals; idxphi2++)
  32. {
  33. phi2 = (-pi/2)+(idxphi2*pi)/number_of_intervals;
  34. for (int idxphi1 = 0; idxphi1 <= number_of_intervals; idxphi1++)
  35. {
  36. phi1 = (-pi/2)+(idxphi1*pi)/number_of_intervals;
  37. for (int idxtheta = 0; idxtheta <= number_of_intervals; idxtheta++)
  38. {
  39. theta = -pi+(idxtheta*(2*pi))/number_of_intervals;
  40. ::std::cout << "theta = " << theta << " ; ";
  41. ::std::cout << "phi1 = " << phi1 << " ; ";
  42. ::std::cout << "phi2 = " << phi2;
  43. ::std::cout << ::std::endl;
  44. ::boost::math::quaternion<float> q = ::boost::math::spherical(rho, theta, phi1, phi2);
  45. ::std::cout << "q = " << q << ::std::endl;
  46. R3_matrix<float> rot = quaternion_to_R3_rotation(q);
  47. ::std::cout << "rot = ";
  48. ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
  49. ::std::cout << "\t";
  50. ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
  51. ::std::cout << "\t";
  52. ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
  53. ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
  54. ::std::cout << "p = " << p << ::std::endl;
  55. ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
  56. ::std::cout << ::std::endl;
  57. }
  58. }
  59. }
  60. ::std::cout << ::std::endl;
  61. }
  62. void test_SO3_semipolar()
  63. {
  64. ::std::cout << "Testing semipolar:" << ::std::endl;
  65. ::std::cout << ::std::endl;
  66. const float rho = 1.0f;
  67. float alpha;
  68. float theta1;
  69. float theta2;
  70. for (int idxalpha = 0; idxalpha <= number_of_intervals; idxalpha++)
  71. {
  72. alpha = (idxalpha*(pi/2))/number_of_intervals;
  73. for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
  74. {
  75. theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
  76. for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
  77. {
  78. theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
  79. ::std::cout << "alpha = " << alpha << " ; ";
  80. ::std::cout << "theta1 = " << theta1 << " ; ";
  81. ::std::cout << "theta2 = " << theta2;
  82. ::std::cout << ::std::endl;
  83. ::boost::math::quaternion<float> q = ::boost::math::semipolar(rho, alpha, theta1, theta2);
  84. ::std::cout << "q = " << q << ::std::endl;
  85. R3_matrix<float> rot = quaternion_to_R3_rotation(q);
  86. ::std::cout << "rot = ";
  87. ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
  88. ::std::cout << "\t";
  89. ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
  90. ::std::cout << "\t";
  91. ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
  92. ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
  93. ::std::cout << "p = " << p << ::std::endl;
  94. ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
  95. ::std::cout << ::std::endl;
  96. }
  97. }
  98. }
  99. ::std::cout << ::std::endl;
  100. }
  101. void test_SO3_multipolar()
  102. {
  103. ::std::cout << "Testing multipolar:" << ::std::endl;
  104. ::std::cout << ::std::endl;
  105. float rho1;
  106. float rho2;
  107. float theta1;
  108. float theta2;
  109. for (int idxrho = 0; idxrho <= number_of_intervals; idxrho++)
  110. {
  111. rho1 = (idxrho*1.0f)/number_of_intervals;
  112. rho2 = ::std::sqrt(1.0f-rho1*rho1);
  113. for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
  114. {
  115. theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
  116. for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
  117. {
  118. theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
  119. ::std::cout << "rho1 = " << rho1 << " ; ";
  120. ::std::cout << "theta1 = " << theta1 << " ; ";
  121. ::std::cout << "theta2 = " << theta2;
  122. ::std::cout << ::std::endl;
  123. ::boost::math::quaternion<float> q = ::boost::math::multipolar(rho1, theta1, rho2, theta2);
  124. ::std::cout << "q = " << q << ::std::endl;
  125. R3_matrix<float> rot = quaternion_to_R3_rotation(q);
  126. ::std::cout << "rot = ";
  127. ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
  128. ::std::cout << "\t";
  129. ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
  130. ::std::cout << "\t";
  131. ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
  132. ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
  133. ::std::cout << "p = " << p << ::std::endl;
  134. ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
  135. ::std::cout << ::std::endl;
  136. }
  137. }
  138. }
  139. ::std::cout << ::std::endl;
  140. }
  141. void test_SO3_cylindrospherical()
  142. {
  143. ::std::cout << "Testing cylindrospherical:" << ::std::endl;
  144. ::std::cout << ::std::endl;
  145. float t;
  146. float radius;
  147. float longitude;
  148. float latitude;
  149. for (int idxt = 0; idxt <= number_of_intervals; idxt++)
  150. {
  151. t = -1.0f+(idxt*2.0f)/number_of_intervals;
  152. radius = ::std::sqrt(1.0f-t*t);
  153. for (int idxlatitude = 0; idxlatitude <= number_of_intervals; idxlatitude++)
  154. {
  155. latitude = (-pi/2)+(idxlatitude*pi)/number_of_intervals;
  156. for (int idxlongitude = 0; idxlongitude <= number_of_intervals; idxlongitude++)
  157. {
  158. longitude = -pi+(idxlongitude*(2*pi))/number_of_intervals;
  159. ::std::cout << "t = " << t << " ; ";
  160. ::std::cout << "longitude = " << longitude;
  161. ::std::cout << "latitude = " << latitude;
  162. ::std::cout << ::std::endl;
  163. ::boost::math::quaternion<float> q = ::boost::math::cylindrospherical(t, radius, longitude, latitude);
  164. ::std::cout << "q = " << q << ::std::endl;
  165. R3_matrix<float> rot = quaternion_to_R3_rotation(q);
  166. ::std::cout << "rot = ";
  167. ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
  168. ::std::cout << "\t";
  169. ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
  170. ::std::cout << "\t";
  171. ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
  172. ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
  173. ::std::cout << "p = " << p << ::std::endl;
  174. ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
  175. ::std::cout << ::std::endl;
  176. }
  177. }
  178. }
  179. ::std::cout << ::std::endl;
  180. }
  181. void test_SO3_cylindrical()
  182. {
  183. ::std::cout << "Testing cylindrical:" << ::std::endl;
  184. ::std::cout << ::std::endl;
  185. float r;
  186. float angle;
  187. float h1;
  188. float h2;
  189. for (int idxh2 = 0; idxh2 <= number_of_intervals; idxh2++)
  190. {
  191. h2 = -1.0f+(idxh2*2.0f)/number_of_intervals;
  192. for (int idxh1 = 0; idxh1 <= number_of_intervals; idxh1++)
  193. {
  194. h1 = ::std::sqrt(1.0f-h2*h2)*(-1.0f+(idxh2*2.0f)/number_of_intervals);
  195. r = ::std::sqrt(1.0f-h1*h1-h2*h2);
  196. for (int idxangle = 0; idxangle <= number_of_intervals; idxangle++)
  197. {
  198. angle = -pi+(idxangle*(2*pi))/number_of_intervals;
  199. ::std::cout << "angle = " << angle << " ; ";
  200. ::std::cout << "h1 = " << h1;
  201. ::std::cout << "h2 = " << h2;
  202. ::std::cout << ::std::endl;
  203. ::boost::math::quaternion<float> q = ::boost::math::cylindrical(r, angle, h1, h2);
  204. ::std::cout << "q = " << q << ::std::endl;
  205. R3_matrix<float> rot = quaternion_to_R3_rotation(q);
  206. ::std::cout << "rot = ";
  207. ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
  208. ::std::cout << "\t";
  209. ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
  210. ::std::cout << "\t";
  211. ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
  212. ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
  213. ::std::cout << "p = " << p << ::std::endl;
  214. ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
  215. ::std::cout << ::std::endl;
  216. }
  217. }
  218. }
  219. ::std::cout << ::std::endl;
  220. }
  221. void test_SO3()
  222. {
  223. ::std::cout << "Testing SO3:" << ::std::endl;
  224. ::std::cout << ::std::endl;
  225. test_SO3_spherical();
  226. test_SO3_semipolar();
  227. test_SO3_multipolar();
  228. test_SO3_cylindrospherical();
  229. test_SO3_cylindrical();
  230. }
  231. //
  232. // Test of quaternion and R^4 rotation relationship
  233. //
  234. void test_SO4_spherical()
  235. {
  236. ::std::cout << "Testing spherical:" << ::std::endl;
  237. ::std::cout << ::std::endl;
  238. const float rho1 = 1.0f;
  239. const float rho2 = 1.0f;
  240. float theta1;
  241. float phi11;
  242. float phi21;
  243. float theta2;
  244. float phi12;
  245. float phi22;
  246. for (int idxphi21 = 0; idxphi21 <= number_of_intervals; idxphi21++)
  247. {
  248. phi21 = (-pi/2)+(idxphi21*pi)/number_of_intervals;
  249. for (int idxphi22 = 0; idxphi22 <= number_of_intervals; idxphi22++)
  250. {
  251. phi22 = (-pi/2)+(idxphi22*pi)/number_of_intervals;
  252. for (int idxphi11 = 0; idxphi11 <= number_of_intervals; idxphi11++)
  253. {
  254. phi11 = (-pi/2)+(idxphi11*pi)/number_of_intervals;
  255. for (int idxphi12 = 0; idxphi12 <= number_of_intervals; idxphi12++)
  256. {
  257. phi12 = (-pi/2)+(idxphi12*pi)/number_of_intervals;
  258. for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
  259. {
  260. theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
  261. for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
  262. {
  263. theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
  264. ::std::cout << "theta1 = " << theta1 << " ; ";
  265. ::std::cout << "phi11 = " << phi11 << " ; ";
  266. ::std::cout << "phi21 = " << phi21;
  267. ::std::cout << "theta2 = " << theta2 << " ; ";
  268. ::std::cout << "phi12 = " << phi12 << " ; ";
  269. ::std::cout << "phi22 = " << phi22;
  270. ::std::cout << ::std::endl;
  271. ::boost::math::quaternion<float> p1 = ::boost::math::spherical(rho1, theta1, phi11, phi21);
  272. ::std::cout << "p1 = " << p1 << ::std::endl;
  273. ::boost::math::quaternion<float> q1 = ::boost::math::spherical(rho2, theta2, phi12, phi22);
  274. ::std::cout << "q1 = " << q1 << ::std::endl;
  275. ::std::pair< ::boost::math::quaternion<float> , ::boost::math::quaternion<float> > pq1 =
  276. ::std::make_pair(p1,q1);
  277. R4_matrix<float> rot = quaternions_to_R4_rotation(pq1);
  278. ::std::cout << "rot = ";
  279. ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << "\t" << rot.a14 << ::std::endl;
  280. ::std::cout << "\t";
  281. ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << "\t" << rot.a24 << ::std::endl;
  282. ::std::cout << "\t";
  283. ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << "\t" << rot.a34 << ::std::endl;
  284. ::std::cout << "\t";
  285. ::std::cout << "\t" << rot.a41 << "\t" << rot.a42 << "\t" << rot.a43 << "\t" << rot.a44 << ::std::endl;
  286. ::std::pair< ::boost::math::quaternion<float> , ::boost::math::quaternion<float> > pq2 =
  287. R4_rotation_to_quaternions(rot, &pq1);
  288. ::std::cout << "p1 = " << pq2.first << ::std::endl;
  289. ::std::cout << "p2 = " << pq2.second << ::std::endl;
  290. ::std::cout << "round trip discrepancy: " << ::std::sqrt(::boost::math::norm(pq1.first-pq2.first)+::boost::math::norm(pq1.second-pq2.second)) << ::std::endl;
  291. ::std::cout << ::std::endl;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. }
  298. ::std::cout << ::std::endl;
  299. }
  300. void test_SO4()
  301. {
  302. ::std::cout << "Testing SO4:" << ::std::endl;
  303. ::std::cout << ::std::endl;
  304. test_SO4_spherical();
  305. }