tensorindex.cc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/test - Limitations of ra::iota<n>(), formerly TensorIndex.
  3. // (c) Daniel Llorens - 2015
  4. // This library is free software; you can redistribute it and/or modify it under
  5. // the terms of the GNU Lesser General Public License as published by the Free
  6. // Software Foundation; either version 3 of the License, or (at your option) any
  7. // later version.
  8. #include "ra/test.hh"
  9. using std::cout, std::endl, std::flush, ra::TestRecorder;
  10. int main()
  11. {
  12. auto i = ra::_0;
  13. auto j = ra::_1;
  14. TestRecorder tr(std::cout);
  15. {
  16. ra::Big<float, 1> x({4}, i + 1), y { 1, 0, 2, -1 }, z({4}, -1);
  17. ra::Big<float, 2> A({4, 4}, i - 2*j);
  18. ra::Big<float, 2> B({4, 4}, 0.);
  19. // the shape of the expression here is determined by A. This works because of an explicit specialization of single-argument select (from()); the generic version of from() doesn't allow it. Not sure if it should be kept.
  20. A = x(i) * y(j);
  21. 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);
  22. // this won't do what you might expect because the selection op is implicitly outer-product:
  23. // z = A(i, i);
  24. // use a non-product selector instead.
  25. z = 0.;
  26. z = map(A, i, i);
  27. tr.info("diagonal").test_eq(ra::Big<float, 1> {1, 0, 6, -4}, z);
  28. // generally expressions using undefined len iota should use ra::map and not ra::from.
  29. B = 0.;
  30. B = map(A, i, j);
  31. tr.info("copy")
  32. .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);
  33. B = 0.;
  34. B = map(A, j, i);
  35. tr.info("transpose 1").test_eq(transpose({1, 0}, A), B);
  36. // the map will work on either side of =. Note however that map(B, i, j) = map(A, j, i) won't work bc the extent of the overall expr is undelimited.
  37. B = 0.;
  38. map(B, j, i) = A;
  39. tr.info("transpose 2").test_eq(transpose({1, 0}, A), B);
  40. // normal rank agreement can be abused to do some kinds of reductions.
  41. z = 0.;
  42. z += A;
  43. tr.info("reduction last axis").test_eq(ra::Big<float, 1> {2, 4, 6, 8}, z);
  44. // however z += map(A, i, j) doesn't work beucase the extent of the driving term is undelimited.
  45. }
  46. {
  47. ra::Big<float, 2> x({4, 3}, 0);
  48. ra::Big<float, 2> y({4, 3}, i-j);
  49. for_each([&](auto i, auto j, auto forsize)
  50. {
  51. tr.info("i ", i, " j ", j)
  52. .test_eq((x + i - j).at(std::array {i, j}),
  53. y.at(std::array {i, j}));
  54. }, i, j, x);
  55. }
  56. return tr.summary();
  57. }