nested-0.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file nested-0.cc
  3. /// @brief Using nested arrays as if they were arrays if higher rank.
  4. // (c) Daniel Llorens - 2014
  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. // TODO Make more things work and work efficiently.
  10. #include <iostream>
  11. #include <sstream>
  12. #include <iterator>
  13. #include "ra/complex.hh"
  14. #include "ra/test.hh"
  15. #include "ra/ra.hh"
  16. using std::cout, std::endl, std::flush, std::cerr, ra::TestRecorder;
  17. template <class T, int N> using Array = ra::Big<T, N>;
  18. template <class T> using Vec = Array<T, 1>;
  19. int main()
  20. {
  21. TestRecorder tr;
  22. tr.section("operators on nested arrays");
  23. {
  24. // default init is required to make vector-of-vector, but I still want Vec {} to mean 'an empty vector' and not a default-init vector.
  25. {
  26. auto c = Vec<int> {};
  27. tr.test_eq(0, c.size(0));
  28. tr.test_eq(0, c.size());
  29. }
  30. {
  31. auto c = Vec<Vec<int>> { {} , {1}, {1, 2} };
  32. std::ostringstream os;
  33. os << c;
  34. std::istringstream is(os.str());
  35. Vec<Vec<int>> d;
  36. is >> d;
  37. tr.test_eq(3, d.size());
  38. tr.test_eq(d[0], Vec<int>{});
  39. tr.test_eq(d[1], Vec<int>{1});
  40. tr.test_eq(d[2], Vec<int>{1, 2});
  41. // TODO Actually nested 'as if higher rank' should allow just (every(c==d)). This is explicit nesting.
  42. tr.test(every(ra::expr([](auto & c, auto & d) { return every(c==d); }, c.iter(), d.iter())));
  43. }
  44. }
  45. tr.section("selector experiments");
  46. {
  47. // These is an investigation of how to make a(ra::all, i) or a(i, ra::all) work.
  48. // The problem with a(ra::all, i) here is that we probably want to leave the iteration on ra::all for last. Otherwise the indexing is redone for each rank-1 cell.
  49. Vec<int> i = {0, 3, 1, 2};
  50. Array<double, 2> a({4, 4}, ra::_0-ra::_1);
  51. Array<double, 2> b = from([](auto && a, auto && i) -> decltype(auto) { return a(i); }, a.iter<1>(), start(i));
  52. tr.test_eq(a(0, i), b(0));
  53. tr.test_eq(a(1, i), b(1));
  54. tr.test_eq(a(2, i), b(2));
  55. tr.test_eq(a(3, i), b(3));
  56. // The problem with a(i) = a(i, ra::all) is that a(i) returns a nested expression, so it isn't equivalent to a(i, [0 1 ...]), and if we want to write it as a rank 2 expression, we can't use from() as above because the iterator we want is a(i).iter(), it depends on i.
  57. // So ...
  58. }
  59. tr.section("copying btw arrays nested in the same way");
  60. {
  61. Vec<ra::Small<int, 2>> a {{1, 2}, {3, 4}, {5, 6}};
  62. ra::Small<ra::Small<int, 2>, 3> b = a;
  63. tr.test_eq(ra::Small<int, 2> {1, 2}, b(0));
  64. tr.test_eq(ra::Small<int, 2> {3, 4}, b(1));
  65. tr.test_eq(ra::Small<int, 2> {5, 6}, b(2));
  66. b(0) = ra::Small<int, 2> {7, 9};
  67. b(1) = ra::Small<int, 2> {3, 4};
  68. b(2) = ra::Small<int, 2> {1, 6};
  69. a = b;
  70. tr.test_eq(ra::Small<int, 2> {7, 9}, a(0));
  71. tr.test_eq(ra::Small<int, 2> {3, 4}, a(1));
  72. tr.test_eq(ra::Small<int, 2> {1, 6}, a(2));
  73. }
  74. tr.section("TODO copying btw arrays nested in different ways");
  75. {
  76. Vec<ra::Small<int, 2>> a {{1, 2}, {3, 4}, {5, 6}};
  77. Array<int, 2> b({3, 2}, {1, 2, 3, 4, 5, 6});
  78. // there's one level of matching so a(0) matches to b(0, 0) and b(0, 1), a(1) to b(1, 0) and b(1, 1), etc. So this results in a(0) = 1 overwritten with a(0) = 2, etc. finally a = [[2, 2], [4, 4], [6, 6]]. Probably not what we want.
  79. a = b;
  80. // b = a; // dnc b/c [x, y] ← z is ok but z ← [x, y] is not.
  81. cout << a << endl;
  82. }
  83. return tr.summary();
  84. }