sym.cpp 5.7 KB

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