assignment_examples.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. //
  2. // Copyright (c) 2010 Athanasios Iliopoulos
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. #include <boost/numeric/ublas/assignment.hpp>
  9. #include <boost/numeric/ublas/vector.hpp>
  10. #include <boost/numeric/ublas/vector_proxy.hpp>
  11. #include <boost/numeric/ublas/matrix_proxy.hpp>
  12. #include <boost/numeric/ublas/vector_sparse.hpp>
  13. #include <boost/numeric/ublas/matrix_sparse.hpp>
  14. #include <boost/numeric/ublas/io.hpp>
  15. #include <boost/numeric/ublas/matrix.hpp>
  16. using namespace boost::numeric::ublas;
  17. int main() {
  18. // Simple vector fill
  19. vector<double> a(3);
  20. a <<= 0, 1, 2;
  21. std::cout << a << std::endl;
  22. // [ 0 1 2]
  23. // Vector from vector
  24. vector<double> b(7);
  25. b <<= a, 10, a;
  26. std::cout << b << std::endl;
  27. // [ 0 1 2 10 0 1 2]
  28. // Simple matrix fill
  29. matrix<double> A(3,3);
  30. A <<= 0, 1, 2,
  31. 3, 4, 5,
  32. 6, 7, 8;
  33. std::cout << A << std::endl;
  34. // [ 0 1 2 ]
  35. // [ 3 4 5 ]
  36. // [ 6 7 8 ]
  37. // Matrix from vector
  38. A <<= 0, 1, 2,
  39. 3, 4, 5,
  40. a;
  41. std::cout << A << std::endl;
  42. // [ 0 1 2 ]
  43. // [ 3 4 5 ]
  44. // [ 0 1 2 ]
  45. // Matrix from vector - column assignment
  46. A <<= move(0,2), traverse_policy::by_column(),
  47. a;
  48. std::cout << A << std::endl;
  49. // [ 0 1 0 ]
  50. // [ 3 4 1 ]
  51. // [ 0 1 2 ]
  52. // Another matrix from vector example (watch the wraping);
  53. vector<double> c(9); c <<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
  54. A <<= c;
  55. std::cout << A << std::endl;
  56. // [ 1 2 3 ]
  57. // [ 4 5 6 ]
  58. // [ 7 8 9 ]
  59. // If for performance(Benchmarks are not definite about that) or consistency reasons you need to disable wraping:
  60. static next_row_manip endr; //This can be defined globally
  61. A <<= traverse_policy::by_row_no_wrap(),
  62. 1, 2, 3, endr,
  63. 4, 5, 6, endr,
  64. 7, 8, 9, endr;
  65. // [ 1 2 3 ]
  66. // [ 4 5 6 ]
  67. // [ 7 8 9 ]
  68. // If by default you need to disable wraping define
  69. // BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY, in the compilation options,
  70. // so that you avoid typing the "traverse_policy::by_row_no_wrap()".
  71. // Plus and minus assign:
  72. A <<= fill_policy::index_plus_assign(),
  73. 3,2,1;
  74. std::cout << A << std::endl;
  75. // [ 4 4 4 ]
  76. // [ 4 5 6 ]
  77. // [ 7 8 9 ]
  78. // Matrix from proxy
  79. A <<= 0, 1, 2,
  80. project(b, range(3,6)),
  81. a;
  82. std::cout << A << std::endl;
  83. // [ 0 1 2 ]
  84. // [10 0 1 ]
  85. // [ 6 7 8 ]
  86. // Matrix from matrix
  87. matrix<double> B(6,6);
  88. B <<= A, A,
  89. A, A;
  90. std::cout << B << std::endl;
  91. // [ A A ]
  92. // [ A A ]
  93. // Matrix range (vector is similar)
  94. B = zero_matrix<double>(6,6);
  95. matrix_range<matrix<double> > mrB (B, range (1, 4), range (1, 4));
  96. mrB <<= 1,2,3,4,5,6,7,8,9;
  97. std::cout << B << std::endl;
  98. // [ 0 0 0 0 0 0]
  99. // [ 0 1 2 3 0 0]
  100. // [ 0 4 5 6 0 0]
  101. // [ 0 0 0 0 0 0]
  102. // [ 0 0 0 0 0 0]
  103. // [ 0 0 0 0 0 0]
  104. // Horizontal concatenation can be achieved using this trick:
  105. matrix<double> BH(3,9);
  106. BH <<= A, A, A;
  107. std::cout << BH << std::endl;
  108. // [ A A A]
  109. // Vertical concatenation can be achieved using this trick:
  110. matrix<double> BV(9,3);
  111. BV <<= A,
  112. A,
  113. A;
  114. std::cout << BV << std::endl;
  115. // [ A ]
  116. // [ A ]
  117. // [ A ]
  118. // Watch the difference when assigning matrices for different traverse policies:
  119. matrix<double> BR(9,9, 0);
  120. BR <<= traverse_policy::by_row(), // This is the default, so this might as well be omitted.
  121. A, A, A;
  122. std::cout << BR << std::endl;
  123. // [ A A A]
  124. // [ 0 0 0]
  125. // [ 0 0 0]
  126. matrix<double> BC(9,9, 0);
  127. BC <<= traverse_policy::by_column(),
  128. A, A, A;
  129. std::cout << BC << std::endl;
  130. // [ A 0 0]
  131. // [ A 0 0]
  132. // [ A 0 0]
  133. // The following will throw a run-time exception in debug mode (matrix mid-assignment wrap is not allowed) :
  134. // matrix<double> C(7,7);
  135. // C <<= A, A, A;
  136. // Matrix from matrix with index manipulators
  137. matrix<double> C(6,6,0);
  138. C <<= A, move(3,0), A;
  139. // [ A 0 ]
  140. // [ 0 A ]
  141. // A faster way for to construct this dense matrix.
  142. matrix<double> D(6,6);
  143. D <<= A, zero_matrix<double>(3,3),
  144. zero_matrix<double>(3,3), A;
  145. // [ A 0 ]
  146. // [ 0 A ]
  147. // The next_row and next_column index manipulators:
  148. // note: next_row and next_column functions return
  149. // a next_row_manip and and next_column_manip object.
  150. // This is the manipulator we used earlier when we disabled
  151. // wrapping.
  152. matrix<double> E(2,4,0);
  153. E <<= 1, 2, next_row(),
  154. 3, 4, next_column(),5;
  155. std::cout << E << std::endl;
  156. // [ 1 2 0 5 ]
  157. // [ 3 4 0 0 ]
  158. // The begin1 (moves to the begining of the column) index manipulator, begin2 does the same for the row:
  159. matrix<double> F(2,4,0);
  160. F <<= 1, 2, next_row(),
  161. 3, 4, begin1(),5;
  162. std::cout << F << std::endl;
  163. // [ 1 2 5 0 ]
  164. // [ 3 4 0 0 ]
  165. // The move (relative) and move_to(absolute) index manipulators (probably the most useful manipulators):
  166. matrix<double> G(2,4,0);
  167. G <<= 1, 2, move(0,1), 3,
  168. move_to(1,3), 4;
  169. std::cout << G << std::endl;
  170. // [ 1 2 0 3 ]
  171. // [ 0 0 0 4 ]
  172. // Static equivallents (faster) when sizes are known at compile time:
  173. matrix<double> Gs(2,4,0);
  174. Gs <<= 1, 2, move<0,1>(), 3,
  175. move_to<1,3>(), 4;
  176. std::cout << Gs << std::endl;
  177. // [ 1 2 0 3 ]
  178. // [ 0 0 0 4 ]
  179. // Choice of traverse policy (default is "row by row" traverse):
  180. matrix<double> H(2,4,0);
  181. H <<= 1, 2, 3, 4,
  182. 5, 6, 7, 8;
  183. std::cout << H << std::endl;
  184. // [ 1 2 3 4 ]
  185. // [ 5 6 7 8 ]
  186. H <<= traverse_policy::by_column(),
  187. 1, 2, 3, 4,
  188. 5, 6, 7, 8;
  189. std::cout << H << std::endl;
  190. // [ 1 3 5 7 ]
  191. // [ 2 4 6 8 ]
  192. // traverse policy can be changed mid assignment if desired.
  193. matrix<double> H1(4,4,0);
  194. H1 <<= 1, 2, 3, traverse_policy::by_column(), 1, 2, 3;
  195. std::cout << H << std::endl;
  196. // [1 2 3 1]
  197. // [0 0 0 2]
  198. // [0 0 0 3]
  199. // [0 0 0 0]
  200. // note: fill_policy and traverse_policy are namespaces, so you can use them
  201. // by a using statement.
  202. // For compressed and coordinate matrix types a push_back or insert fill policy can be chosen for faster assginment:
  203. compressed_matrix<double> I(2, 2);
  204. I <<= fill_policy::sparse_push_back(),
  205. 0, 1, 2, 3;
  206. std::cout << I << std::endl;
  207. // [ 0 1 ]
  208. // [ 2 3 ]
  209. coordinate_matrix<double> J(2,2);
  210. J<<=fill_policy::sparse_insert(),
  211. 1, 2, 3, 4;
  212. std::cout << J << std::endl;
  213. // [ 1 2 ]
  214. // [ 3 4 ]
  215. // A sparse matrix from another matrix works as with other types.
  216. coordinate_matrix<double> K(3,3);
  217. K<<=fill_policy::sparse_insert(),
  218. J;
  219. std::cout << K << std::endl;
  220. // [ 1 2 0 ]
  221. // [ 3 4 0 ]
  222. // [ 0 0 0 ]
  223. // Be careful this will not work:
  224. //compressed_matrix<double> J2(4,4);
  225. //J2<<=fill_policy::sparse_push_back(),
  226. // J,J;
  227. // That's because the second J2's elements
  228. // are attempted to be assigned at positions
  229. // that come before the elements already pushed.
  230. // Unfortunatelly that's the only thing you can do in this case
  231. // (or of course make a custom agorithm):
  232. compressed_matrix<double> J2(4,4);
  233. J2<<=fill_policy::sparse_push_back(),
  234. J, fill_policy::sparse_insert(),
  235. J;
  236. std::cout << J2 << std::endl;
  237. // [ J J ]
  238. // [ 0 0 0 0 ]
  239. // [ 0 0 0 0 ]
  240. // A different traverse policy doesn't change the result, only they order it is been assigned.
  241. coordinate_matrix<double> L(3,3);
  242. L<<=fill_policy::sparse_insert(), traverse_policy::by_column(),
  243. J;
  244. std::cout << L << std::endl;
  245. // (same as previous)
  246. // [ 1 2 0 ]
  247. // [ 3 4 0 ]
  248. // [ 0 0 0 ]
  249. typedef coordinate_matrix<double>::size_type cmst;
  250. const cmst size = 30;
  251. //typedef fill_policy::sparse_push_back spb;
  252. // Although the above could have been used the following is may be faster if
  253. // you use the policy often and for relatively small containers.
  254. static fill_policy::sparse_push_back spb;
  255. // A block diagonal sparse using a loop:
  256. compressed_matrix<double> M(size, size, 4*15);
  257. for (cmst i=0; i!=size; i+=J.size1())
  258. M <<= spb, move_to(i,i), J;
  259. // If typedef was used above the last expression should start
  260. // with M <<= spb()...
  261. // Displaying so that blocks can be easily seen:
  262. for (unsigned int i=0; i!=M.size1(); i++) {
  263. std::cout << M(i,0);
  264. for (unsigned int j=1; j!=M.size2(); j++) std::cout << ", " << M(i,j);
  265. std::cout << "\n";
  266. }
  267. // [ J 0 0 0 ... 0]
  268. // [ 0 J 0 0 ... 0]
  269. // [ 0 . . . ... 0]
  270. // [ 0 0 ... 0 0 J]
  271. // A "repeat" trasverser may by provided so that this becomes faster and an on-liner like:
  272. // M <<= spb, repeat(0, size, J.size1(), 0, size, J.size1()), J;
  273. // An alternate would be to create a :repeater" matrix and vector expression that can be used in other places as well. The latter is probably better,
  274. return 0;
  275. }