test-tensorindex.C 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // (c) Daniel Llorens - 2015
  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-tensorindex.C
  7. /// @brief Limitations of ra::TensorIndex.
  8. #include "ra/operators.H"
  9. #include "ra/io.H"
  10. #include "ra/test.H"
  11. using std::cout; using std::endl; using std::flush;
  12. int main()
  13. {
  14. constexpr auto i = ra::_0;
  15. constexpr auto j = ra::_1;
  16. // constexpr auto k = ra::_2;
  17. TestRecorder tr(std::cout);
  18. {
  19. ra::Big<float, 1> x({4}, i + 1), y { 1, 0, 2, -1 }, z({4}, -1);
  20. ra::Big<float, 2> A({4, 4}, i - 2*j);
  21. ra::Big<float, 2> B({4, 4}, 0.);
  22. // the shape of the expression here is determined by A. This works because of an explicit specialization of single-argument select (from()) in wrank.H; the generic version of from() doesn't allow it. Not sure if it should be kept.
  23. A = x(i) * y(j);
  24. tr.test_eq(ra::Big<float, 2>({4, 4}, {1, 0, 2, -1, 2, 0, 4, -2, 3, 0, 6, -3, 4, 0, 8, -4}), A);
  25. // this won't do what you might expect because the selection op is implicitly outer-product:
  26. // z = A(i, i);
  27. // use a non-product selector instead.
  28. z = 0.;
  29. z = map(A, i, i);
  30. tr.info("diagonal").test_eq(ra::Big<float, 1> {1, 0, 6, -4}, z);
  31. // generally expressions using undelimited subscript TensorIndex should use ra::map and not ra::from.
  32. B = 0.;
  33. B = map(A, i, j);
  34. tr.info("copy")
  35. .test_eq(ra::Big<float, 2>({4, 4}, {1, 0, 2, -1, 2, 0, 4, -2, 3, 0, 6, -3, 4, 0, 8, -4}), B);
  36. B = 0.;
  37. B = map(A, j, i);
  38. tr.info("transpose 1").test_eq(transpose({1, 0}, A), B);
  39. // the map will work on either side of =. Note however that map(B, i, j) = map(A, j, i) won't work b/c the extent of the overall expr is undelimited.
  40. B = 0.;
  41. map(B, j, i) = A;
  42. tr.info("transpose 2").test_eq(transpose({1, 0}, A), B);
  43. // normal rank agreement can be abused to do some kinds of reductions.
  44. z = 0.;
  45. z += A;
  46. tr.info("reduction last axis").test_eq(ra::Big<float, 1> {2, 4, 6, 8}, z);
  47. // however z += map(A, i, j) doesn't work beucase the extent of the driving term is undelimited.
  48. }
  49. return tr.summary();
  50. }