frame-old.C 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file frame-old.C
  3. /// @brief Frame-matching tests for pre v10 Expr, previously in test/ra-0.C.
  4. // (c) Daniel Llorens - 2013-2014, 2019
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #include <iostream>
  10. #include <iterator>
  11. #include <numeric>
  12. #include "ra/format.H"
  13. // -------------------------------------
  14. // bit from example/throw.C which FIXME should be easier. Maybe an option in ra/macros.H.
  15. struct ra_error: public std::exception
  16. {
  17. std::string s;
  18. template <class ... A> ra_error(A && ... a): s(ra::format(std::forward<A>(a) ...)) {}
  19. virtual char const * what() const throw ()
  20. {
  21. return s.c_str();
  22. }
  23. };
  24. #ifdef RA_ASSERT
  25. #error RA_ASSERT is already defined!
  26. #endif
  27. #define RA_ASSERT( cond, ... ) \
  28. { if (!( cond )) throw ra_error("ra:: assert [" STRINGIZE(cond) "]", __VA_ARGS__); }
  29. // -------------------------------------
  30. #include "ra/complex.H"
  31. #include "ra/test.H"
  32. #include "ra/big.H"
  33. #include "test/old.H"
  34. using std::cout, std::endl, std::flush;
  35. using real = double;
  36. int main()
  37. {
  38. TestRecorder tr;
  39. tr.section("frame matching - TensorIndex/Scalar");
  40. {
  41. // driver is highest rank, which is ra::_0 (1).
  42. constexpr auto e = ra::_0+1;
  43. static_assert(e.rank_s()==1, "bad rank_s");
  44. static_assert(e.rank()==1, "bad rank");
  45. static_assert(e.size_s(0)==ra::DIM_BAD, "bad size");
  46. }
  47. tr.section("frame matching - Unique/TensorIndex");
  48. {
  49. ra::Unique<real, 2> c({3, 2}, ra::none);
  50. ra::Unique<real, 2> a({3, 2}, ra::none);
  51. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  52. std::iota(a.begin(), a.end(), 1);
  53. std::fill(c.begin(), c.end(), 0);
  54. ply_index(expr([](real & c, real a, int b) { c = a-(b+1); },
  55. c.iter(), a.iter(), ra::_0));
  56. tr.test_eq(check, c);
  57. std::fill(c.begin(), c.end(), 0);
  58. ply_index(expr([](real & c, int a, real b) { c = b-(a+1); },
  59. c.iter(), ra::_0, a.iter()));
  60. tr.test_eq(check, c);
  61. }
  62. tr.section("frame matching - Unique/TensorIndex - TensorIndex can't be driving arg");
  63. {
  64. ra::Unique<real, 2> c({3, 2}, ra::none);
  65. ra::Unique<real, 2> a({3, 2}, ra::none);
  66. real check[3][2] = { {0, 0}, {2, 2}, {4, 4} };
  67. std::iota(a.begin(), a.end(), 1);
  68. std::fill(c.begin(), c.end(), 0);
  69. ply_index(expr([](real a, int b, real & c) { c = a-(b+1); },
  70. a.iter(), ra::_1, c.iter()));
  71. tr.test_eq(check, c);
  72. std::fill(c.begin(), c.end(), 0);
  73. ply_index(expr([](int a, real b, real & c) { c = b-(a+1); },
  74. ra::_1, a.iter(), c.iter()));
  75. tr.test_eq(check, c);
  76. }
  77. #define TEST(plier) \
  78. std::fill(c.begin(), c.end(), 0); \
  79. plier(expr([](real & c, real a, real b) { c = a-b; }, \
  80. c.iter(), a.iter(), b.iter())); \
  81. tr.test_eq(check, c); \
  82. \
  83. std::fill(c.begin(), c.end(), 0); \
  84. plier(expr([](real & c, real a, real b) { c = b-a; }, \
  85. c.iter(), b.iter(), a.iter())); \
  86. tr.test_eq(check, c);
  87. tr.section("frame matching - Unique/Unique");
  88. {
  89. ra::Unique<real, 2> c({3, 2}, ra::none);
  90. ra::Unique<real, 2> a({3, 2}, ra::none);
  91. ra::Unique<real, 1> b({3}, ra::none);
  92. std::iota(a.begin(), a.end(), 1);
  93. std::iota(b.begin(), b.end(), 1);
  94. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  95. TEST(ply_ravel);
  96. TEST(ply_index);
  97. }
  98. tr.section("frame matching - Unique/Small");
  99. {
  100. ra::Unique<real, 2> c({3, 2}, ra::none);
  101. ra::Unique<real, 2> a({3, 2}, ra::none);
  102. ra::Small<real, 3> b;
  103. std::iota(a.begin(), a.end(), 1);
  104. std::iota(b.begin(), b.end(), 1);
  105. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  106. TEST(ply_ravel);
  107. TEST(ply_index);
  108. }
  109. tr.section("frame matching - Small/Small");
  110. {
  111. ra::Small<real, 3, 2> c;
  112. ra::Small<real, 3, 2> a;
  113. ra::Small<real, 3> b;
  114. std::iota(a.begin(), a.end(), 1);
  115. std::iota(b.begin(), b.end(), 1);
  116. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  117. TEST(ply_ravel);
  118. TEST(ply_index);
  119. }
  120. #undef TEST
  121. tr.section("frame match is good only for full expr, so test on ply, not construction");
  122. {
  123. ra::Unique<real, 2> a({2, 2}, 0.);
  124. ra::Unique<real, 1> b {1., 2.};
  125. // note that b-c has no driver, but all that matters is that the full expression does.
  126. auto e = expr([](real & a, real bc) { a = bc; },
  127. a.iter(), expr([](real b, real c) { return b-c; }, b.iter(), ra::_1));
  128. ply_index(e);
  129. tr.test_eq(1, a(0, 0));
  130. tr.test_eq(0, a(0, 1));
  131. tr.test_eq(2, a(1, 0));
  132. tr.test_eq(1, a(1, 1));
  133. }
  134. tr.section("frame matching should-be-error cases");
  135. {
  136. ra::Unique<real, 1> a({3}, 10);
  137. ra::Unique<real, 1> b({4}, 1);
  138. auto plus2real_print = [](real a, real b) { cout << (a - b) << " "; };
  139. int x = 0;
  140. try {
  141. ply_ravel(ra::expr(plus2real_print, a.iter(), b.iter()));
  142. x = 1;
  143. } catch (ra_error & e) {
  144. }
  145. tr.info("caught error").test_eq(0, x);
  146. }
  147. tr.section("frame matching should-be-error cases - dynamic rank");
  148. {
  149. ra::Unique<real> a({3}, 10);
  150. ra::Unique<real> b({4}, 1);
  151. auto plus2real_print = [](real a, real b) { cout << (a - b) << " "; };
  152. int x = 0;
  153. try {
  154. ply_ravel(ra::expr(plus2real_print, a.iter(), b.iter()));
  155. x = 1;
  156. } catch (ra_error & e) {
  157. }
  158. tr.info("caught error").test_eq(0, x);
  159. }
  160. tr.section("unintiuitive behavior [ra33]");
  161. {
  162. ra::Big<int, 1> i = {0, 1, 2};
  163. ra::Big<double, 2> A({3, 2}, ra::_0 - ra::_1);
  164. ra::Big<double, 2> F({3, 2}, 0.);
  165. iter<-1>(F) = A(i); // A(i) returns a nested expression. FIXME Should it?
  166. tr.test_eq(A, F);
  167. }
  168. return tr.summary();
  169. }