tensorindex.C 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file tensorindex.C
  3. /// @brief Limitations of ra::TensorIndex.
  4. // (c) Daniel Llorens - 2015
  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 "ra/operators.H"
  10. #include "ra/io.H"
  11. #include "ra/test.H"
  12. using std::cout, std::endl, std::flush;
  13. int main()
  14. {
  15. auto i = ra::_0;
  16. auto j = ra::_1;
  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. }