test-frame-match.C 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // (c) Daniel Llorens - 2013-2014
  2. // This library is free software; you can redistribute it and/or modify it under
  3. // the terms of the GNU Lesser General Public License as published by the Free
  4. // Software Foundation; either version 3 of the License, or (at your option) any
  5. // later version.
  6. /// @file test-frame-matching.C
  7. /// @brief Specific frame-matching tests, previously in test-ra-0.C.
  8. #include <iostream>
  9. #include <iterator>
  10. #include <numeric>
  11. #include "ra/complex.H"
  12. #include "ra/test.H"
  13. #include "ra/big.H"
  14. using std::cout; using std::endl; using std::flush;
  15. using real = double;
  16. int main()
  17. {
  18. TestRecorder tr;
  19. tr.section("frame matching - TensorIndex/Scalar");
  20. {
  21. // driver is highest rank, which is ra::_0 (1).
  22. auto e = ra::_0+1;
  23. static_assert(e.rank_s()==1, "bad driver"); // TODO CWG1684 should allow .rank() (gcc bug #66297)
  24. // but TensorIndex cannot be a driver.
  25. static_assert(!(decltype(e)::VALID_DRIVER), "bad driver check");
  26. }
  27. tr.section("frame matching - Unique/TensorIndex");
  28. {
  29. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  30. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  31. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  32. std::iota(a.begin(), a.end(), 1);
  33. std::fill(c.begin(), c.end(), 0);
  34. ply_index(expr([](real & c, real a, int b) { c = a-(b+1); },
  35. c.iter(), a.iter(), ra::_0));
  36. tr.test_eq(check, c);
  37. std::fill(c.begin(), c.end(), 0);
  38. ply_index(expr([](real & c, int a, real b) { c = b-(a+1); },
  39. c.iter(), ra::_0, a.iter()));
  40. tr.test_eq(check, c);
  41. }
  42. tr.section("frame matching - Unique/TensorIndex - TensorIndex can't be driving arg");
  43. {
  44. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  45. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  46. real check[3][2] = { {0, 0}, {2, 2}, {4, 4} };
  47. std::iota(a.begin(), a.end(), 1);
  48. std::fill(c.begin(), c.end(), 0);
  49. ply_index(expr([](real a, int b, real & c) { c = a-(b+1); },
  50. a.iter(), ra::_1, c.iter()));
  51. tr.test_eq(check, c);
  52. std::fill(c.begin(), c.end(), 0);
  53. ply_index(expr([](int a, real b, real & c) { c = b-(a+1); },
  54. ra::_1, a.iter(), c.iter()));
  55. tr.test_eq(check, c);
  56. }
  57. #define TEST(plier) \
  58. std::fill(c.begin(), c.end(), 0); \
  59. plier(expr([](real & c, real a, real b) { c = a-b; }, \
  60. c.iter(), a.iter(), b.iter())); \
  61. tr.test_eq(check, c); \
  62. \
  63. std::fill(c.begin(), c.end(), 0); \
  64. plier(expr([](real & c, real a, real b) { c = b-a; }, \
  65. c.iter(), b.iter(), a.iter())); \
  66. tr.test_eq(check, c);
  67. tr.section("frame matching - Unique/Unique");
  68. {
  69. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  70. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  71. ra::Unique<real, 1> b({3}, ra::unspecified);
  72. std::iota(a.begin(), a.end(), 1);
  73. std::iota(b.begin(), b.end(), 1);
  74. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  75. TEST(ply_ravel);
  76. TEST(ply_index);
  77. }
  78. tr.section("frame matching - Unique/Small");
  79. {
  80. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  81. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  82. ra::Small<real, 3> b;
  83. std::iota(a.begin(), a.end(), 1);
  84. std::iota(b.begin(), b.end(), 1);
  85. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  86. TEST(ply_ravel);
  87. TEST(ply_index);
  88. }
  89. tr.section("frame matching - Small/Small");
  90. {
  91. ra::Small<real, 3, 2> c;
  92. ra::Small<real, 3, 2> a;
  93. ra::Small<real, 3> b;
  94. std::iota(a.begin(), a.end(), 1);
  95. std::iota(b.begin(), b.end(), 1);
  96. real check[3][2] = { {0, 1}, {1, 2}, {2, 3} };
  97. TEST(ply_ravel);
  98. TEST(ply_index);
  99. }
  100. #undef TEST
  101. tr.section("frame match is good only for full expr, so test on ply, not construction");
  102. {
  103. ra::Unique<real, 2> a({2, 2}, 0.);
  104. ra::Unique<real, 1> b {1., 2.};
  105. // note that b-c has no driver, but all that matters is that the full expression does.
  106. auto e = expr([](real & a, real bc) { a = bc; },
  107. a.iter(), expr([](real b, real c) { return b-c; }, b.iter(), ra::_1));
  108. static_assert(e.A==0, "bad driver selection");
  109. ply_index(e);
  110. tr.test_eq(1, a(0, 0));
  111. tr.test_eq(0, a(0, 1));
  112. tr.test_eq(2, a(1, 0));
  113. tr.test_eq(1, a(1, 1));
  114. }
  115. tr.section("frame matching should-be-error cases [untested]");
  116. // TODO Check that this is an error.
  117. // {
  118. // ra::Unique<real, 1> a {3};
  119. // ra::Unique<real, 1> b {4};
  120. // std::iota(a.begin(), a.end(), 10);
  121. // std::iota(b.begin(), b.end(), 1);
  122. // cout << "a: " << a << endl;
  123. // cout << "b: " << b << endl;
  124. // auto plus2real_print = [](real a, real b) { cout << (a - b) << " "; };
  125. // ply_ravel(ra::expr(plus2real_print, a.iter(), b.iter()));
  126. // }
  127. // TODO Check that this is an error.
  128. // TODO This also requires that ra::expr handles dynamic rank.
  129. // {
  130. // ra::Unique<real> a {3};
  131. // ra::Unique<real> b {4};
  132. // std::iota(a.begin(), a.end(), 10);
  133. // std::iota(b.begin(), b.end(), 1);
  134. // cout << "a: " << a << endl;
  135. // cout << "b: " << b << endl;
  136. // auto plus2real_print = [](real a, real b) { cout << (a - b) << " "; };
  137. // ply_ravel(ra::expr(plus2real_print, a.iter(), b.iter()));
  138. // }
  139. tr.section("unintiuitive behavior [ra33]");
  140. {
  141. ra::Big<int, 1> i = {0, 1, 2};
  142. ra::Big<double, 2> A({3, 2}, ra::_0 - ra::_1);
  143. ra::Big<double, 2> F({3, 2}, 0.);
  144. iter<-1>(F) = A(i); // A(i) returns a nested expression. FIXME Should it?
  145. tr.test_eq(A, F);
  146. }
  147. return tr.summary();
  148. }