tensorindex.cc 2.3 KB

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