sym.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include <iostream>
  2. #include <string>
  3. #include <cassert>
  4. #include <sstream>
  5. #include <algorithm>
  6. #include "simple/geom/vector.hpp"
  7. #include "simple/geom/algorithm.hpp"
  8. using namespace std::literals;
  9. using namespace simple::geom;
  10. std::stringstream ss;
  11. struct sym
  12. {
  13. std::string val;
  14. #define DEFINE_SYM_OPERATOR(op) \
  15. sym operator op(sym s) const \
  16. { \
  17. if(!val.empty()) \
  18. s.val = val + #op + s.val; \
  19. return s; \
  20. } \
  21. sym& operator op##=(sym s) \
  22. { \
  23. (*this) = (*this) op s; \
  24. return (*this); \
  25. }
  26. DEFINE_SYM_OPERATOR(+)
  27. DEFINE_SYM_OPERATOR(-)
  28. DEFINE_SYM_OPERATOR(*)
  29. DEFINE_SYM_OPERATOR(/)
  30. DEFINE_SYM_OPERATOR(%)
  31. #undef DEFINE_SYM_OPERATOR
  32. friend std::ostream& operator<<(std::ostream& os, const sym& s)
  33. {
  34. return os << s.val;
  35. }
  36. };
  37. template <typename... Cs>
  38. auto sym_vector(Cs... cs)
  39. {
  40. return vector(sym{cs}...);
  41. }
  42. template<typename T, size_t D, typename O>
  43. const auto& vector_only_geometric_product = dot_wedge<T, D, O>;
  44. template<typename T, size_t D, typename O>
  45. const auto& make_rotor = dot_wedge<T, D, O>;
  46. void Explode()
  47. {
  48. const auto wrap_in_vector = [](const auto &x) {return vector(x);};
  49. auto a = vector( sym_vector("x1", "x2", "x3") ); // 3x1
  50. auto b = sym_vector("y1", "y2", "y3").transformed(wrap_in_vector); // 1x3
  51. ss << a(b); // 3x1 * 1x3 = 3x3
  52. assert( ss.str() ==
  53. R"(^^^
  54. (x1*y1, x2*y1, x3*y1)
  55. (x1*y2, x2*y2, x3*y2)
  56. (x1*y3, x2*y3, x3*y3)
  57. vvv
  58. )"
  59. ); ss.str("");
  60. ss << b(a); // 1x3 * 3x1 = 1x1
  61. assert( ss.str() ==
  62. R"(^
  63. (y1*x1+y2*x2+y3*x3)
  64. v
  65. )"
  66. ); ss.str("");
  67. auto ab = vector(a(b)); // 3x3x1
  68. ss << ab(b); // 3x3x1 * 1x3 = 3x3x3
  69. assert( ss.str() ==
  70. R"(^^^
  71. ^^^
  72. (x1*y1*y1, x2*y1*y1, x3*y1*y1)
  73. (x1*y2*y1, x2*y2*y1, x3*y2*y1)
  74. (x1*y3*y1, x2*y3*y1, x3*y3*y1)
  75. vvv
  76. ^^^
  77. (x1*y1*y2, x2*y1*y2, x3*y1*y2)
  78. (x1*y2*y2, x2*y2*y2, x3*y2*y2)
  79. (x1*y3*y2, x2*y3*y2, x3*y3*y2)
  80. vvv
  81. ^^^
  82. (x1*y1*y3, x2*y1*y3, x3*y1*y3)
  83. (x1*y2*y3, x2*y2*y3, x3*y2*y3)
  84. (x1*y3*y3, x2*y3*y3, x3*y3*y3)
  85. vvv
  86. vvv
  87. )"
  88. ); ss.str("");
  89. ss << b(ab); // 1x3 * 3x3x1 = 1x3x1
  90. assert( ss.str() ==
  91. R"(^^^
  92. ^
  93. (y1*x1*y1+y2*x2*y1+y3*x3*y1)
  94. (y1*x1*y2+y2*x2*y2+y3*x3*y2)
  95. (y1*x1*y3+y2*x2*y3+y3*x3*y3)
  96. v
  97. vvv
  98. )"
  99. ); ss.str("");
  100. ss << (ab(b))(ab); // brace yourselves: 3x3x3 * 3x3x1 = 3x3x3x1
  101. assert( ss.str() ==
  102. R"(^^^
  103. ^^^
  104. ^^^
  105. (x1*y1*y1*x1*y1+x1*y1*y2*x2*y1+x1*y1*y3*x3*y1, x2*y1*y1*x1*y1+x2*y1*y2*x2*y1+x2*y1*y3*x3*y1, x3*y1*y1*x1*y1+x3*y1*y2*x2*y1+x3*y1*y3*x3*y1)
  106. (x1*y2*y1*x1*y1+x1*y2*y2*x2*y1+x1*y2*y3*x3*y1, x2*y2*y1*x1*y1+x2*y2*y2*x2*y1+x2*y2*y3*x3*y1, x3*y2*y1*x1*y1+x3*y2*y2*x2*y1+x3*y2*y3*x3*y1)
  107. (x1*y3*y1*x1*y1+x1*y3*y2*x2*y1+x1*y3*y3*x3*y1, x2*y3*y1*x1*y1+x2*y3*y2*x2*y1+x2*y3*y3*x3*y1, x3*y3*y1*x1*y1+x3*y3*y2*x2*y1+x3*y3*y3*x3*y1)
  108. vvv
  109. ^^^
  110. (x1*y1*y1*x1*y2+x1*y1*y2*x2*y2+x1*y1*y3*x3*y2, x2*y1*y1*x1*y2+x2*y1*y2*x2*y2+x2*y1*y3*x3*y2, x3*y1*y1*x1*y2+x3*y1*y2*x2*y2+x3*y1*y3*x3*y2)
  111. (x1*y2*y1*x1*y2+x1*y2*y2*x2*y2+x1*y2*y3*x3*y2, x2*y2*y1*x1*y2+x2*y2*y2*x2*y2+x2*y2*y3*x3*y2, x3*y2*y1*x1*y2+x3*y2*y2*x2*y2+x3*y2*y3*x3*y2)
  112. (x1*y3*y1*x1*y2+x1*y3*y2*x2*y2+x1*y3*y3*x3*y2, x2*y3*y1*x1*y2+x2*y3*y2*x2*y2+x2*y3*y3*x3*y2, x3*y3*y1*x1*y2+x3*y3*y2*x2*y2+x3*y3*y3*x3*y2)
  113. vvv
  114. ^^^
  115. (x1*y1*y1*x1*y3+x1*y1*y2*x2*y3+x1*y1*y3*x3*y3, x2*y1*y1*x1*y3+x2*y1*y2*x2*y3+x2*y1*y3*x3*y3, x3*y1*y1*x1*y3+x3*y1*y2*x2*y3+x3*y1*y3*x3*y3)
  116. (x1*y2*y1*x1*y3+x1*y2*y2*x2*y3+x1*y2*y3*x3*y3, x2*y2*y1*x1*y3+x2*y2*y2*x2*y3+x2*y2*y3*x3*y3, x3*y2*y1*x1*y3+x3*y2*y2*x2*y3+x3*y2*y3*x3*y3)
  117. (x1*y3*y1*x1*y3+x1*y3*y2*x2*y3+x1*y3*y3*x3*y3, x2*y3*y1*x1*y3+x2*y3*y2*x2*y3+x2*y3*y3*x3*y3, x3*y3*y1*x1*y3+x3*y3*y2*x2*y3+x3*y3*y3*x3*y3)
  118. vvv
  119. vvv
  120. vvv
  121. )"
  122. ); ss.str("");
  123. auto a2 = vector( sym_vector("a", "b") ); // 2x1
  124. auto b2 = sym_vector("c", "d").transformed(wrap_in_vector); // 1x2
  125. ss << a2(b2) << '\n';
  126. ss << dot_wedge(
  127. sym_vector("a", "b"),
  128. sym_vector("c", "d")
  129. ) << '\n';
  130. ss << dot_wedge(
  131. sym_vector("u1", "u2", "u3"),
  132. sym_vector("v1", "v2", "v3")
  133. ) << '\n';
  134. // (a + ib)(c + id) = ac + aid + ibc + iibd = (ac - bd) + (ad + bc)i
  135. // (a + ib)(c - id) = ac - aid + ibc - iibd = (ac + bd) + (bc - ad)i
  136. // ((ac - bd) + (ad + bc)i)(a-ib) = (ac - bd)(a-ib) + (ad+bc)i(a-ib) =
  137. // = aca - acib - bda + bdib + adia + bcia - adiib - bciib =
  138. // = aca - bda + bdib + adia + adb + bcb
  139. assert(ss.str() ==
  140. R"(^^
  141. (a*c, b*c)
  142. (a*d, b*d)
  143. vv
  144. (b*c-a*d, a*c+b*d)
  145. (u2*v1-u1*v2, u3*v1-u1*v3, u3*v2-u2*v3, u1*v1+u2*v2+u3*v3)
  146. )"
  147. ); ss.str("");
  148. auto aa = vector(
  149. sym_vector("x1", "x2"),
  150. sym_vector("x3", "x4")
  151. );
  152. auto bb = vector(
  153. sym_vector("y1", "y2"),
  154. sym_vector("y3", "y4")
  155. );
  156. auto A = vector( aa ); // 2x2x1
  157. auto B = bb.transformed([&](auto x){ return x.transformed(wrap_in_vector);}); // 1x2x2
  158. ss << A(B); // 2x2x1 * 1x2x2 = 2x2x2x2
  159. assert(ss.str() ==
  160. R"(^^
  161. ^^
  162. ^^
  163. (x1*y1, x2*y1)
  164. (x3*y1, x4*y1)
  165. vv
  166. ^^
  167. (x1*y2, x2*y2)
  168. (x3*y2, x4*y2)
  169. vv
  170. vv
  171. ^^
  172. ^^
  173. (x1*y3, x2*y3)
  174. (x3*y3, x4*y3)
  175. vv
  176. ^^
  177. (x1*y4, x2*y4)
  178. (x3*y4, x4*y4)
  179. vv
  180. vv
  181. vv
  182. )"
  183. ); ss.str("");
  184. }
  185. int main()
  186. {
  187. Explode();
  188. {
  189. auto a = sym_vector("a", "b", "c");
  190. auto m = vector(
  191. sym_vector("x1", "y1", "z1"),
  192. sym_vector("x2", "y2", "z2"),
  193. sym_vector("x3", "y3", "z3")
  194. );
  195. std::cout << m(a) << '\n';
  196. std::cout << a(m) << '\n';
  197. }
  198. {
  199. auto a = sym_vector("x1", "y1", "z1");
  200. auto b = sym_vector("x2", "y2", "z2");
  201. std::cout << "=============== EXPAND ============" << '\n';
  202. std::cout << dot_wedge(b,a) << '\n';
  203. }
  204. // return {y1*z2 - y2*z1, z1*x2 - z2*x1, x1*y2 - x2*y1};
  205. return 0;
  206. }