user.html 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  2. "http://www.w3.org/TR/html4/loose.dtd">
  3. <html>
  4. <!--
  5. == Copyright 2002 The Trustees of Indiana University.
  6. == Use, modification and distribution is subject to the Boost Software
  7. == License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. == http://www.boost.org/LICENSE_1_0.txt)
  9. == Boost.MultiArray Library
  10. == Authors: Ronald Garcia
  11. == Jeremy Siek
  12. == Andrew Lumsdaine
  13. == See http://www.boost.org/libs/multi_array for documentation.
  14. -->
  15. <head>
  16. <title>The Boost Multidimensional Array Library (Boost.MultiArray)</title>
  17. </head>
  18. <body>
  19. <h1>
  20. <img src="../../../boost.png" alt="boost logo"
  21. width="277" align="middle" height="86">
  22. <br>The Boost Multidimensional Array Library
  23. <br>(Boost.MultiArray)
  24. </h1>
  25. <h2>Synopsis</h2>
  26. <p>
  27. The Boost Multidimensional Array Library provides a class template for
  28. multidimensional arrays, as well as semantically equivalent
  29. adaptors for arrays of contiguous data. The classes in this library
  30. implement a common interface, formalized as a generic programming
  31. concept. The interface design is in line with the precedent set by the
  32. C++ Standard Library containers. Boost MultiArray is a more efficient
  33. and convenient way to express N-dimensional arrays than existing
  34. alternatives (especially the
  35. <tt>std::vector&lt;std::vector&lt;...&gt;&gt;</tt> formulation
  36. of N-dimensional arrays). The arrays provided by the library may be
  37. accessed using the familiar syntax of native C++ arrays. Additional
  38. features, such as resizing, reshaping, and creating views are
  39. available (and described below).
  40. <h2>Table of Contents</h2>
  41. <ol>
  42. <li><a href="#sec_introduction">Introduction</a>
  43. <li><a href="#sec_example">Short Example</a>
  44. <li><a href="#sec_components">MultiArray Components</a>
  45. <li><a href="#sec_assignment">Construction and Assignment</a>
  46. <li><a href="#sec_generators">Array View and Subarray Type Generators</a>
  47. <li><a href="#sec_dimensions">Specifying Array Dimensions</a>
  48. <li><a href="#sec_access">Accessing Elements</a>
  49. <li><a href="#sec_views">Creating Views</a>
  50. <li><a href="#sec_storage">Storage Ordering</a>
  51. <li><a href="#sec_base">Setting the Array Base</a>
  52. <li><a href="#sec_reshape">Changing an Array's Shape</a>
  53. <li><a href="#sec_resize">Resizing an Array</a>
  54. <li><a href="#sec_concepts">MultiArray Concept</a>
  55. <li><a href="#sec_testcases">Test Cases</a>
  56. <li><a href="#sec_related">Related Work</a>
  57. <li><a href="#sec_credits">Credits</a>
  58. </ol>
  59. <a name="sec_introduction"></a>
  60. <h2>Introduction</h2>
  61. <p>
  62. The C++ standard library provides several generic containers, but it
  63. does not provide any multidimensional array types. The
  64. <tt>std::vector</tt> class template can be used to implement
  65. N-dimensional arrays, for example expressing a 2-dimensional array of
  66. <tt>double</tt> elements using the type
  67. <tt>std::vector&lt;std::vector&lt;double&gt;&gt;</tt>, but the
  68. resulting interface is unwieldy and the memory overhead can be quite
  69. high. Native C++ arrays (i.e. <tt>int arr[2][2][2];</tt>) do not
  70. immediately interoperate well with the C++ Standard Library, and they
  71. also lose information at function call boundaries (specifically the
  72. extent of the last dimension). Finally, a dynamically allocated
  73. contiguous block of elements can be treated as an array, though this
  74. method requires manual bookkeeping that is error prone and obfuscates
  75. the intent of the programmer.
  76. </p>
  77. <p>
  78. The Boost MultiArray library enhances the C++ standard containers with
  79. versatile multi-dimensional array abstractions. It includes a general
  80. array class template and native array adaptors that support idiomatic
  81. array operations and interoperate with C++ Standard Library containers
  82. and algorithms. The arrays share a common interface, expressed as a
  83. generic programming in terms of which generic array algorithms can be
  84. implemented.
  85. </p>
  86. <p>
  87. This document is meant to provide an introductory tutorial and user's
  88. guide for the most basic and common usage patterns of MultiArray
  89. components. The <a href="./reference.html">reference manual</a>
  90. provides more complete and formal documentation of library features.
  91. </p>
  92. <a name="sec_example"></a>
  93. <h2>Short Example</h2>
  94. What follows is a brief example of the use of <tt>multi_array</tt>:
  95. <blockquote>
  96. <pre>
  97. #include "boost/multi_array.hpp"
  98. #include &lt;cassert&gt;
  99. int
  100. main () {
  101. // Create a 3D array that is 3 x 4 x 2
  102. typedef boost::multi_array&lt;double, 3&gt; array_type;
  103. typedef array_type::index index;
  104. array_type A(boost::extents[3][4][2]);
  105. // Assign values to the elements
  106. int values = 0;
  107. for(index i = 0; i != 3; ++i)
  108. for(index j = 0; j != 4; ++j)
  109. for(index k = 0; k != 2; ++k)
  110. A[i][j][k] = values++;
  111. // Verify values
  112. int verify = 0;
  113. for(index i = 0; i != 3; ++i)
  114. for(index j = 0; j != 4; ++j)
  115. for(index k = 0; k != 2; ++k)
  116. assert(A[i][j][k] == verify++);
  117. return 0;
  118. }
  119. </pre>
  120. </blockquote>
  121. <a name="sec_components"></a>
  122. <h2>MultiArray Components</h2>
  123. Boost.MultiArray's implementation (boost/multi_array.hpp) provides three user-level class templates:
  124. <ol>
  125. <li><a href="./reference.html#multi_array"><tt>multi_array</tt></a>,
  126. <li><a href="./reference.html#multi_array_ref"><tt>multi_array_ref</tt></a>, and
  127. <li><a href="./reference.html#const_multi_array_ref"><tt>const_multi_array_ref</tt></a>
  128. </ol>
  129. <tt>multi_array</tt> is a container template. When instantiated, it
  130. allocates space for the number of elements corresponding to the
  131. dimensions specified at construction time. A <tt>multi_array</tt> may
  132. also be default constructed and resized as needed.
  133. <p>
  134. <tt>multi_array_ref</tt> adapts an existing array of data to provide
  135. the <tt>multi_array</tt> interface. <tt>multi_array_ref</tt> does not own the
  136. data passed to it.
  137. <p>
  138. <tt>const_multi_array_ref</tt> is similar to <tt>multi_array_ref</tt>
  139. but guarantees that the contents of the array are immutable. It can
  140. thus wrap pointers of type <i>T const*</i>.
  141. <p>
  142. The three components exhibit very similar behavior. Aside from
  143. constructor parameters, <tt>multi_array</tt> and
  144. <tt>multi_array_ref</tt> export the same interface.
  145. <tt>const_multi_array_ref</tt> provides only the constness-preserving
  146. portions of the <tt>multi_array_ref</tt> interface.
  147. <a name="sec_assignment"></a>
  148. <h2>Construction and Assignment</h2>
  149. <p>Each of the array types -
  150. <a href="./reference.html#multi_array"><tt>multi_array</tt></a>,
  151. <a href="./reference.html#multi_array_ref"><tt>multi_array_ref</tt></a>, and
  152. <a href="./reference.html#const_multi_array_ref"><tt>const_multi_array_ref</tt></a> -
  153. provides a specialized set of constructors. For further information,
  154. consult their reference pages.
  155. <p>All of the non-const array types in this library provide assignment
  156. operators<tt>operator=()</tt>. Each of the array types <tt>multi_array</tt>,
  157. <tt>multi_array_ref</tt>, <tt>subarray</tt>, and
  158. <tt>array_view</tt> can be assigned from any
  159. of the others, so long as their shapes match. The
  160. const variants, <tt>const_multi_array_ref</tt>,
  161. <tt>const_subarray</tt>, and <tt>const_array_view</tt>, can be the
  162. source of a copy to an array with matching shape.
  163. Assignment results in a deep (element by element) copy of the data
  164. contained within an array.
  165. <a name="sec_generators"></a>
  166. <h2>Array View and Subarray Type Generators</h2>
  167. In some situations, the use of nested generators for array_view and
  168. subarray types is inconvenient. For example, inside a
  169. function template parameterized upon array type, the extra
  170. "template" keywords can be obfuscating. More likely though, some
  171. compilers cannot handle templates nested within template parameters.
  172. For this reason the type generators, <tt>subarray_gen</tt>,
  173. <tt>const_subarray_gen</tt>, <tt>array_view_gen</tt>, and
  174. <tt>const_array_view_gen</tt> are provided. Thus, the two typedefs
  175. in the following example result in the same type:
  176. <blockquote>
  177. <pre>
  178. template &lt;typename Array&gt;
  179. void my_function() {
  180. typedef typename Array::template array_view&lt;3&gt;::type view1_t;
  181. typedef typename boost::array_view_gen&lt;Array,3&gt;::type view2_t;
  182. // ...
  183. }
  184. </pre>
  185. </blockquote>
  186. <a name="sec_dimensions"></a>
  187. <h2>Specifying Array Dimensions</h2>
  188. When creating most of the Boost.MultiArray components, it is necessary
  189. to specify both the number of dimensions and the extent of each
  190. (<tt>boost::multi_array</tt> also provides a default constructor).
  191. Though the number of dimensions is always specified as a template
  192. parameter, two separate mechanisms have been provided to specify the
  193. extent of each.
  194. <p>The first method involves passing a
  195. <a href="../../utility/Collection.html">
  196. Collection</a> of extents to a
  197. constructor, most commonly a <tt>boost::array</tt>. The constructor
  198. will retrieve the beginning iterator from the container and retrieve N
  199. elements, corresponding to extents for the N dimensions. This is
  200. useful for writing dimension-independent code.
  201. <h3>Example</h3>
  202. <blockquote>
  203. <pre>
  204. typedef boost::multi_array&lt;double, 3&gt; array_type;
  205. boost::array&lt;array_type::index, 3&gt; shape = {{ 3, 4, 2 }};
  206. array_type A(shape);
  207. </pre>
  208. </blockquote>
  209. <p>The second method involves passing the constructor an <tt>extent_gen</tt>
  210. object, specifying the matrix dimensions. The <tt>extent_gen</tt> type
  211. is defined in the <tt>multi_array_types</tt> namespace and as a
  212. member of every array type, but by default, the library constructs a
  213. global <tt>extent_gen</tt> object <tt>boost::extents</tt>. In case of
  214. concern about memory used by these objects, defining
  215. <tt>BOOST_MULTI_ARRAY_NO_GENERATORS</tt> before including the library
  216. header inhibits its construction.
  217. <h3>Example</h3>
  218. <blockquote>
  219. <pre>
  220. typedef boost::multi_array&lt;double, 3&gt; array_type;
  221. array_type A(boost::extents[3][4][2]);
  222. </pre>
  223. </blockquote>
  224. <a name="sec_access"></a>
  225. <h2>Accessing Elements</h2>
  226. The Boost.MultiArray components provide two ways of accessing
  227. specific elements within a container. The first uses the traditional
  228. C array notation, provided by <tt>operator[]</tt>.
  229. <h3>Example</h3>
  230. <blockquote>
  231. <pre>
  232. typedef boost::multi_array&lt;double, 3&gt; array_type;
  233. array_type A(boost::extents[3][4][2]);
  234. A[0][0][0] = 3.14;
  235. assert(A[0][0][0] == 3.14);
  236. </pre>
  237. </blockquote>
  238. <p> The second method involves passing a
  239. <a href="../../utility/Collection.html">
  240. Collection</a> of indices to <tt>operator()</tt>. N indices will be retrieved
  241. from the Collection for the N dimensions of the container.
  242. <h3>Example</h3>
  243. <blockquote>
  244. <pre>
  245. typedef boost::multi_array&lt;double, 3&gt; array_type;
  246. array_type A(boost::extents[3][4][2]);
  247. boost::array&lt;array_type::index,3&gt; idx = {{0,0,0}};
  248. A(idx) = 3.14;
  249. assert(A(idx) == 3.14);
  250. </pre>
  251. </blockquote>
  252. This can be useful for writing dimension-independent code, and under
  253. some compilers may yield higher performance than <tt>operator[].</tt>
  254. <p>
  255. By default, both of the above element access methods perform range
  256. checking. If a supplied index is out of the range defined for an
  257. array, an assertion will abort the program. To disable range
  258. checking (for performance reasons in production releases), define
  259. the <tt>BOOST_DISABLE_ASSERTS</tt> preprocessor macro prior to
  260. including multi_array.hpp in your application.
  261. <a name="sec_views"></a>
  262. <h2>Creating Views</h2>
  263. Boost.MultiArray provides the facilities for creating a sub-view of an
  264. already existing array component. It allows you to create a sub-view that
  265. retains the same number of dimensions as the original array or one
  266. that has less dimensions than the original as well.
  267. <p>Sub-view creation occurs by placing a call to operator[], passing
  268. it an <tt>index_gen</tt> type. The <tt>index_gen</tt> is populated by
  269. passing <tt>index_range</tt> objects to its <tt>operator[]</tt>.
  270. The <tt>index_range</tt> and <tt>index_gen</tt> types are defined in
  271. the <tt>multi_array_types</tt> namespace and as nested members of
  272. every array type. Similar to <tt>boost::extents</tt>, the library by
  273. default constructs the object <tt>boost::indices</tt>. You can
  274. suppress this object by
  275. defining <tt>BOOST_MULTI_ARRAY_NO_GENERATORS</tt> before including the
  276. library header. A simple sub-view creation example follows.
  277. <h3>Example</h3>
  278. <blockquote>
  279. <pre>
  280. // myarray = 2 x 3 x 4
  281. //
  282. // array_view dims: [base,bound) (dimension striding default = 1)
  283. // dim 0: [0,2)
  284. // dim 1: [1,3)
  285. // dim 2: [0,4) (strided by 2),
  286. //
  287. typedef boost::multi_array_types::index_range range;
  288. // OR typedef array_type::index_range range;
  289. array_type::array_view&lt;3&gt;::type myview =
  290. myarray[ boost::indices[range(0,2)][range(1,3)][range(0,4,2)] ];
  291. for (array_type::index i = 0; i != 2; ++i)
  292. for (array_type::index j = 0; j != 2; ++j)
  293. for (array_type::index k = 0; k != 2; ++k)
  294. assert(myview[i][j][k] == myarray[i][j+1][k*2]);
  295. </pre>
  296. </blockquote>
  297. <p>By passing an integral value to the index_gen, one may create a
  298. subview with fewer dimensions than the original array component (also
  299. called slicing).
  300. <h3>Example</h3>
  301. <blockquote>
  302. <pre>
  303. // myarray = 2 x 3 x 4
  304. //
  305. // array_view dims:
  306. // [base,stride,bound)
  307. // [0,1,2), 1, [0,2,4)
  308. //
  309. typedef boost::multi_array_types::index_range range;
  310. array_type::index_gen indices;
  311. array_type::array_view&lt;2&gt;::type myview =
  312. myarray[ indices[range(0,2)][1][range(0,4,2)] ];
  313. for (array_type::index i = 0; i != 2; ++i)
  314. for (array_type::index j = 0; j != 2; ++j)
  315. assert(myview[i][j] == myarray[i][1][j*2]);
  316. </pre>
  317. </blockquote>
  318. <h3>More on <tt>index_range</tt></h3>
  319. The <tt>index_range</tt> type provides several methods of specifying
  320. ranges for subview generation. Here are a few range instantiations
  321. that specify the same range.
  322. <h3>Example</h3>
  323. <blockquote>
  324. <pre>
  325. // [base,stride,bound)
  326. // [0,2,4)
  327. typedef boost::multi_array_types::index_range range;
  328. range a_range;
  329. a_range = range(0,4,2);
  330. a_range = range().start(0).finish(4).stride(2);
  331. a_range = range().start(0).stride(2).finish(4);
  332. a_range = 0 &lt;= range().stride(2) &lt; 4;
  333. a_range = 0 &lt;= range().stride(2) &lt;= 3;
  334. </pre>
  335. </blockquote>
  336. An <tt>index_range</tt> object passed to a slicing operation will
  337. inherit its start and/or finish value from the array being sliced if
  338. you do not supply one. This conveniently prevents you from having to
  339. know the bounds of the array dimension in certain cases. For example,
  340. the default-constructed range will take the full extent of the
  341. dimension it is used to specify.
  342. <h3>Example</h3>
  343. <blockquote>
  344. <pre>
  345. typedef boost::multi_array_types::index_range range;
  346. range a_range;
  347. // All elements in this dimension
  348. a_range = range();
  349. // indices i where 3 &lt;= i
  350. a_range = range().start(3)
  351. a_range = 3 &lt;= range();
  352. a_range = 2 &lt; range();
  353. // indices i where i &lt; 7
  354. a_range = range().finish(7)
  355. a_range = range() &lt; 7;
  356. a_range = range() &lt;= 6;
  357. </pre>
  358. </blockquote>
  359. The following example slicing operations exhibit some of the
  360. alternatives shown above
  361. <blockquote>
  362. <pre>
  363. // take all of dimension 1
  364. // take i &lt; 5 for dimension 2
  365. // take 4 &lt;= j &lt;= 7 for dimension 3 with stride 2
  366. myarray[ boost::indices[range()][range() &lt; 5 ][4 &lt;= range().stride(2) &lt;= 7] ];
  367. </pre>
  368. </blockquote>
  369. <a name="sec_storage"></a>
  370. <h2>Storage Ordering</h2>
  371. Each array class provides constructors that accept a storage ordering
  372. parameter. This is most
  373. useful when interfacing with legacy codes that require an ordering
  374. different from standard C, such as FORTRAN. The possibilities are
  375. <tt>c_storage_order</tt>, <tt>fortran_storage_order</tt>, and
  376. <tt>general_storage_order</tt>.
  377. <p><tt>c_storage_order</tt>, which is the default, will store elements
  378. in memory in the same order as a C array would, that is, the
  379. dimensions are stored from last to first.
  380. <p><tt>fortran_storage_order</tt> will store elements in memory in the same order
  381. as FORTRAN would: from the first dimension to
  382. the last. Note that with use of this parameter, the array
  383. indices will remain zero-based.
  384. <h3>Example</h3>
  385. <blockquote>
  386. <pre>
  387. typedef boost::multi_array&lt;double,3&gt; array_type;
  388. array_type A(boost::extents[3][4][2],boost::fortran_storage_order());
  389. call_fortran_function(A.data());
  390. </pre>
  391. </blockquote>
  392. <p><tt>general_storage_order</tt> allows one to customize both the order in
  393. which dimensions are stored in memory and whether dimensions are
  394. stored in ascending or descending order.
  395. <h3>Example</h3>
  396. <blockquote>
  397. <pre>
  398. typedef boost::general_storage_order&lt;3&gt; storage;
  399. typedef boost::multi_array&lt;int,3&gt; array_type;
  400. // Store last dimension, then first, then middle
  401. array_type::size_type ordering[] = {2,0,1};
  402. // Store the first dimension(dimension 0) in descending order
  403. bool ascending[] = {false,true,true};
  404. array_type A(extents[3][4][2],storage(ordering,ascending));
  405. </pre>
  406. </blockquote>
  407. <a name="sec_base"></a>
  408. <h2>Setting The Array Base</h2>
  409. In some situations, it may be inconvenient or awkward to use an
  410. array that is zero-based.
  411. the Boost.MultiArray components provide two facilities for changing the
  412. bases of an array. One may specify a pair of range values, with
  413. the <tt>extent_range</tt> type, to
  414. the <tt>extent_gen</tt> constructor in order to set the base value.
  415. <h3>Example</h3>
  416. <blockquote>
  417. <pre>
  418. typedef boost::multi_array&lt;double, 3&gt; array_type;
  419. typedef boost::multi_array_types::extent_range range;
  420. // OR typedef array_type::extent_range range;
  421. array_type::extent_gen extents;
  422. // dimension 0: 0-based
  423. // dimension 1: 1-based
  424. // dimension 2: -1 - based
  425. array_type A(extents[2][range(1,4)][range(-1,3)]);
  426. </pre>
  427. </blockquote>
  428. <p>
  429. An alternative is to first construct the array normally then
  430. reset the bases. To set all bases to the same value, use the
  431. <tt>reindex</tt> member function, passing it a single new index value.
  432. <h3>Example</h3>
  433. <blockquote>
  434. <pre>
  435. typedef boost::multi_array&lt;double, 3&gt; array_type;
  436. array_type::extent_gen extents;
  437. array_type A(extents[2][3][4]);
  438. // change to 1-based
  439. A.reindex(1)
  440. </pre>
  441. </blockquote>
  442. <p>
  443. An alternative is to set each base separately using the
  444. <tt>reindex</tt> member function, passing it a Collection of index bases.
  445. <h3>Example</h3>
  446. <blockquote>
  447. <pre>
  448. typedef boost::multi_array&lt;double, 3&gt; array_type;
  449. array_type::extent_gen extents;
  450. // dimension 0: 0-based
  451. // dimension 1: 1-based
  452. // dimension 2: (-1)-based
  453. array_type A(extents[2][3][4]);
  454. boost::array&lt;array_type::index,ndims&gt; bases = {{0, 1, -1}};
  455. A.reindex(bases);
  456. </pre>
  457. </blockquote>
  458. <a name="sec_reshape"></a>
  459. <h2>Changing an Array's Shape</h2>
  460. The Boost.MultiArray arrays provide a reshape operation. While the
  461. number of dimensions must remain the same, the shape of the array may
  462. change so long as the total number of
  463. elements contained remains the same.
  464. <h3>Example</h3>
  465. <blockquote>
  466. <pre>
  467. typedef boost::multi_array&lt;double, 3&gt; array_type;
  468. array_type::extent_gen extents;
  469. array_type A(extents[2][3][4]);
  470. boost::array&lt;array_type::index,ndims&gt; dims = {{4, 3, 2}};
  471. A.reshape(dims);
  472. </pre>
  473. </blockquote>
  474. <p>
  475. Note that reshaping an array does not affect the indexing.
  476. <a name="sec_resize"></a>
  477. <h2>Resizing an Array</h2>
  478. The <tt>boost::multi_array</tt> class provides an element-preserving
  479. resize operation. The number of dimensions must remain the same, but
  480. the extent of each dimension may be increased and decreased as
  481. desired. When an array is made strictly larger, the existing elements
  482. will be preserved by copying them into the new underlying memory and
  483. subsequently destructing the elements in the old underlying memory.
  484. Any new elements in the array are default constructed. However, if
  485. the new array size shrinks some of the dimensions, some elements will
  486. no longer be available.
  487. <h3>Example</h3>
  488. <blockquote>
  489. <pre>
  490. typedef boost::multi_array&lt;int, 3&gt; array_type;
  491. array_type::extent_gen extents;
  492. array_type A(extents[3][3][3]);
  493. A[0][0][0] = 4;
  494. A[2][2][2] = 5;
  495. A.resize(extents[2][3][4]);
  496. assert(A[0][0][0] == 4);
  497. // A[2][2][2] is no longer valid.
  498. </pre>
  499. </blockquote>
  500. <a name="sec_concepts"></a>
  501. <h2>MultiArray Concept</h2>
  502. Boost.MultiArray defines and uses the
  503. <a href="./reference.html#MultiArray">MultiArray</a>
  504. concept. It specifies an interface for N-dimensional containers.
  505. <a name="sec_testcases"></a>
  506. <h2>Test Cases</h2>
  507. Boost.MultiArray comes with a suite of test cases meant to exercise
  508. the features and semantics of the library. A description of the test
  509. cases can be found <a href="./test_cases.html">here</a>.
  510. <a name="sec_related"></a>
  511. <h2>Related Work</h2>
  512. <a href="../../array/index.html">boost::array</a>
  513. and <a href="https://www.boost.org/sgi/stl/Vector.html">std::vector</a> are
  514. one-dimensional containers of user data. Both manage their own
  515. memory. <tt>std::valarray</tt> is a low-level
  516. C++ Standard Library component
  517. meant to provide portable high performance for numerical applications.
  518. <a href="http://www.oonumerics.org/blitz/">Blitz++</a> is
  519. an array library developed by Todd
  520. Veldhuizen. It uses
  521. advanced C++ techniques to provide near-Fortran performance for
  522. array-based numerical applications.
  523. <b>array_traits</b> is a beta library, formerly distributed with
  524. Boost, that provides a means to create iterators over native C++
  525. arrays.
  526. This library is analogous to
  527. <a href="../../array/index.html">boost::array</a> in that it augments C style N-dimensional
  528. arrays, as <tt>boost::array</tt> does for C one-dimensional arrays.
  529. <a name="sec_credits"></a>
  530. <h2>Credits</h2>
  531. <ul>
  532. <li><a href="mailto:garcia@osl.iu.edu">Ronald Garcia</a>
  533. is the primary author of the library.
  534. <li><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>
  535. helped with the library and provided a sounding board for ideas,
  536. advice, and assistance porting to Microsoft Visual C++.
  537. <li><a href="mailto:gbavestrelli@yahoo.com">Giovanni Bavestrelli</a>
  538. provided an early implementation of an
  539. N-dimensional array which inspired feedback from the
  540. <a href="http://www.boost.org/">Boost</a> mailing list
  541. members. Some design decisions in this work were based upon this
  542. implementation and the comments it elicited.
  543. <li><a href="mailto:tveldhui@acm.org">Todd Veldhuizen</a> wrote
  544. <a href="http://oonumerics.org/blitz/">Blitz++</a>, which
  545. inspired some aspects of this design. In addition, he supplied
  546. feedback on the design and implementation of the library.
  547. <li><a href="mailto:jewillco@osl.iu.edu">Jeremiah Willcock</a>
  548. provided feedback on the implementation and design of the
  549. library and some suggestions for features.
  550. <li><a href="mailto:bdawes@acm.org">Beman Dawes</a>
  551. helped immensely with porting the library to Microsoft Windows
  552. compilers.
  553. <li><a href="mailto:glenjofe@gmail.com">Glen Fernandes</a>
  554. implemented support for the C++11 allocator model, including
  555. support for stateful allocators, minimal allocators, and
  556. optimized storage for stateless allocators.
  557. </ul>
  558. <hr>
  559. <address>
  560. <a href="mailto:garcia@.cs.indiana.edu">Ronald Garcia</a>
  561. </address>
  562. <!-- Created: Fri Jun 29 10:53:07 EST 2001 -->
  563. <!-- hhmts start -->Last modified: Tue Feb 7 17:15:50 EST 2006 <!-- hhmts end -->
  564. </body>
  565. </html>