test-ra-frame-matching.C 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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-ra-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/ra-large.H"
  14. using std::cout; using std::endl; using std::flush;
  15. int main()
  16. {
  17. TestRecorder tr;
  18. section("frame matching - TensorIndex/Scalar");
  19. {
  20. // driver is highest rank, which is ra::_0 (1).
  21. auto e = ra::_0+1;
  22. static_assert(e.rank_s()==1, "bad driver"); // @TODO CWG1684 should allow .rank() (gcc bug #66297)
  23. // but TensorIndex cannot be a driver.
  24. static_assert(decltype(e)::HAS_DRIVER==0, "bad driver check");
  25. }
  26. section("frame matching - Unique/TensorIndex");
  27. {
  28. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  29. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  30. std::iota(a.begin(), a.end(), 1);
  31. real check[6] = { 0, 1, 1, 2, 2, 3 };
  32. std::fill(c.begin(), c.end(), 0);
  33. ply_index(expr([](real & c, real a, int b) { c = a-(b+1); },
  34. c.iter(), a.iter(), ra::_0));
  35. tr.test(std::equal(check, check+6, c.begin()));
  36. std::fill(c.begin(), c.end(), 0);
  37. ply_index(expr([](real & c, int a, real b) { c = b-(a+1); },
  38. c.iter(), ra::_0, a.iter()));
  39. tr.test(std::equal(check, check+6, c.begin()));
  40. }
  41. section("frame matching - Unique/TensorIndex - TensorIndex can't be driving arg");
  42. {
  43. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  44. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  45. std::iota(a.begin(), a.end(), 1);
  46. real check[6] = { 0, 0, 2, 2, 4, 4 };
  47. std::fill(c.begin(), c.end(), 0);
  48. ply_index(expr([](real a, int b, real & c) { c = a-(b+1); },
  49. a.iter(), ra::_1, c.iter()));
  50. tr.test(std::equal(check, check+6, c.begin()));
  51. std::fill(c.begin(), c.end(), 0);
  52. ply_index(expr([](int a, real b, real & c) { c = b-(a+1); },
  53. ra::_1, a.iter(), c.iter()));
  54. tr.test(std::equal(check, check+6, c.begin()));
  55. }
  56. #define TEST(plier) \
  57. std::fill(c.begin(), c.end(), 0); \
  58. plier(expr([](real & c, real a, real b) { c = a-b; }, \
  59. c.iter(), a.iter(), b.iter())); \
  60. tr.test(std::equal(check, check+6, c.begin())); \
  61. \
  62. std::fill(c.begin(), c.end(), 0); \
  63. plier(expr([](real & c, real a, real b) { c = b-a; }, \
  64. c.iter(), b.iter(), a.iter())); \
  65. tr.test(std::equal(check, check+6, c.begin()));
  66. section("frame matching - Unique/Unique");
  67. {
  68. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  69. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  70. ra::Unique<real, 1> b({3}, ra::unspecified);
  71. std::iota(a.begin(), a.end(), 1);
  72. std::iota(b.begin(), b.end(), 1);
  73. real check[6] = { 0, 1, 1, 2, 2, 3 };
  74. TEST(ply_ravel);
  75. TEST(ply_index);
  76. }
  77. section("frame matching - Unique/Small");
  78. {
  79. ra::Unique<real, 2> c({3, 2}, ra::unspecified);
  80. ra::Unique<real, 2> a({3, 2}, ra::unspecified);
  81. ra::Small<real, 3> b;
  82. std::iota(a.begin(), a.end(), 1);
  83. std::iota(b.begin(), b.end(), 1);
  84. real check[6] = { 0, 1, 1, 2, 2, 3 };
  85. TEST(ply_ravel);
  86. TEST(ply_index);
  87. }
  88. section("frame matching - Small/Small");
  89. {
  90. ra::Small<real, 3, 2> c;
  91. ra::Small<real, 3, 2> a;
  92. ra::Small<real, 3> b;
  93. std::iota(a.begin(), a.end(), 1);
  94. std::iota(b.begin(), b.end(), 1);
  95. real check[6] = { 0, 1, 1, 2, 2, 3 };
  96. TEST(ply_ravel);
  97. TEST(ply_index);
  98. }
  99. #undef TEST
  100. section("frame match is good only for full expr, so test on ply, not construction");
  101. {
  102. ra::Unique<real, 2> a({2, 2}, 0.);
  103. ra::Unique<real, 1> b {1., 2.};
  104. // note that b-c has no driver, but all that matters is that the full expression does.
  105. auto e = expr([](real & a, real bc) { a = bc; },
  106. a.iter(), expr([](real b, real c) { return b-c; }, b.iter(), ra::_1));
  107. static_assert(e.A==0, "bad driver selection");
  108. ply_index(e);
  109. tr.test_eq(1, a(0, 0));
  110. tr.test_eq(0, a(0, 1));
  111. tr.test_eq(2, a(1, 0));
  112. tr.test_eq(1, a(1, 1));
  113. }
  114. section("frame matching should-be-error cases [untested]");
  115. // @TODO Check that this is an error.
  116. // {
  117. // ra::Unique<real, 1> a {3};
  118. // ra::Unique<real, 1> b {4};
  119. // std::iota(a.begin(), a.end(), 10);
  120. // std::iota(b.begin(), b.end(), 1);
  121. // cout << "a: " << a << endl;
  122. // cout << "b: " << b << endl;
  123. // auto plus2real_print = [](real a, real b) { cout << (a - b) << " "; };
  124. // ply_ravel(ra::expr(plus2real_print, a.iter(), b.iter()));
  125. // }
  126. // @TODO Check that this is an error.
  127. // @TODO This also requires that ra::expr handles dynamic rank.
  128. // {
  129. // ra::Unique<real> a {3};
  130. // ra::Unique<real> b {4};
  131. // std::iota(a.begin(), a.end(), 10);
  132. // std::iota(b.begin(), b.end(), 1);
  133. // cout << "a: " << a << endl;
  134. // cout << "b: " << b << endl;
  135. // auto plus2real_print = [](real a, real b) { cout << (a - b) << " "; };
  136. // ply_ravel(ra::expr(plus2real_print, a.iter(), b.iter()));
  137. // }
  138. return tr.summary();
  139. }