681 lines
23 KiB
HTML
681 lines
23 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
"http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<!--
|
|
== Copyright 2002 The Trustees of Indiana University.
|
|
|
|
== Use, modification and distribution is subject to the Boost Software
|
|
== License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
== http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
== Boost.MultiArray Library
|
|
== Authors: Ronald Garcia
|
|
== Jeremy Siek
|
|
== Andrew Lumsdaine
|
|
== See http://www.boost.org/libs/multi_array for documentation.
|
|
-->
|
|
<head>
|
|
<title>The Boost Multidimensional Array Library (Boost.MultiArray)</title>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<h1>
|
|
<img src="../../../boost.png" alt="boost logo"
|
|
width="277" align="middle" height="86">
|
|
<br>The Boost Multidimensional Array Library
|
|
<br>(Boost.MultiArray)
|
|
</h1>
|
|
|
|
<h2>Synopsis</h2>
|
|
|
|
<p>
|
|
The Boost Multidimensional Array Library provides a class template for
|
|
multidimensional arrays, as well as semantically equivalent
|
|
adaptors for arrays of contiguous data. The classes in this library
|
|
implement a common interface, formalized as a generic programming
|
|
concept. The interface design is in line with the precedent set by the
|
|
C++ Standard Library containers. Boost MultiArray is a more efficient
|
|
and convenient way to express N-dimensional arrays than existing
|
|
alternatives (especially the
|
|
<tt>std::vector<std::vector<...>></tt> formulation
|
|
of N-dimensional arrays). The arrays provided by the library may be
|
|
accessed using the familiar syntax of native C++ arrays. Additional
|
|
features, such as resizing, reshaping, and creating views are
|
|
available (and described below).
|
|
|
|
|
|
<h2>Table of Contents</h2>
|
|
|
|
<ol>
|
|
<li><a href="#sec_introduction">Introduction</a>
|
|
|
|
<li><a href="#sec_example">Short Example</a>
|
|
|
|
<li><a href="#sec_components">MultiArray Components</a>
|
|
|
|
<li><a href="#sec_assignment">Construction and Assignment</a>
|
|
|
|
<li><a href="#sec_generators">Array View and Subarray Type Generators</a>
|
|
|
|
<li><a href="#sec_dimensions">Specifying Array Dimensions</a>
|
|
|
|
<li><a href="#sec_access">Accessing Elements</a>
|
|
|
|
<li><a href="#sec_views">Creating Views</a>
|
|
|
|
<li><a href="#sec_storage">Storage Ordering</a>
|
|
|
|
<li><a href="#sec_base">Setting the Array Base</a>
|
|
|
|
<li><a href="#sec_reshape">Changing an Array's Shape</a>
|
|
|
|
<li><a href="#sec_resize">Resizing an Array</a>
|
|
|
|
<li><a href="#sec_concepts">MultiArray Concept</a>
|
|
|
|
<li><a href="#sec_testcases">Test Cases</a>
|
|
|
|
<li><a href="#sec_related">Related Work</a>
|
|
<li><a href="#sec_credits">Credits</a>
|
|
</ol>
|
|
|
|
|
|
<a name="sec_introduction"></a>
|
|
<h2>Introduction</h2>
|
|
|
|
<p>
|
|
The C++ standard library provides several generic containers, but it
|
|
does not provide any multidimensional array types. The
|
|
<tt>std::vector</tt> class template can be used to implement
|
|
N-dimensional arrays, for example expressing a 2-dimensional array of
|
|
<tt>double</tt> elements using the type
|
|
<tt>std::vector<std::vector<double>></tt>, but the
|
|
resulting interface is unwieldy and the memory overhead can be quite
|
|
high. Native C++ arrays (i.e. <tt>int arr[2][2][2];</tt>) do not
|
|
immediately interoperate well with the C++ Standard Library, and they
|
|
also lose information at function call boundaries (specifically the
|
|
extent of the last dimension). Finally, a dynamically allocated
|
|
contiguous block of elements can be treated as an array, though this
|
|
method requires manual bookkeeping that is error prone and obfuscates
|
|
the intent of the programmer.
|
|
</p>
|
|
|
|
<p>
|
|
The Boost MultiArray library enhances the C++ standard containers with
|
|
versatile multi-dimensional array abstractions. It includes a general
|
|
array class template and native array adaptors that support idiomatic
|
|
array operations and interoperate with C++ Standard Library containers
|
|
and algorithms. The arrays share a common interface, expressed as a
|
|
generic programming in terms of which generic array algorithms can be
|
|
implemented.
|
|
</p>
|
|
|
|
<p>
|
|
This document is meant to provide an introductory tutorial and user's
|
|
guide for the most basic and common usage patterns of MultiArray
|
|
components. The <a href="./reference.html">reference manual</a>
|
|
provides more complete and formal documentation of library features.
|
|
</p>
|
|
|
|
<a name="sec_example"></a>
|
|
<h2>Short Example</h2>
|
|
What follows is a brief example of the use of <tt>multi_array</tt>:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
#include "boost/multi_array.hpp"
|
|
#include <cassert>
|
|
|
|
int
|
|
main () {
|
|
// Create a 3D array that is 3 x 4 x 2
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
typedef array_type::index index;
|
|
array_type A(boost::extents[3][4][2]);
|
|
|
|
// Assign values to the elements
|
|
int values = 0;
|
|
for(index i = 0; i != 3; ++i)
|
|
for(index j = 0; j != 4; ++j)
|
|
for(index k = 0; k != 2; ++k)
|
|
A[i][j][k] = values++;
|
|
|
|
// Verify values
|
|
int verify = 0;
|
|
for(index i = 0; i != 3; ++i)
|
|
for(index j = 0; j != 4; ++j)
|
|
for(index k = 0; k != 2; ++k)
|
|
assert(A[i][j][k] == verify++);
|
|
|
|
return 0;
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="sec_components"></a>
|
|
<h2>MultiArray Components</h2>
|
|
|
|
Boost.MultiArray's implementation (boost/multi_array.hpp) provides three user-level class templates:
|
|
|
|
<ol>
|
|
<li><a href="./reference.html#multi_array"><tt>multi_array</tt></a>,
|
|
|
|
<li><a href="./reference.html#multi_array_ref"><tt>multi_array_ref</tt></a>, and
|
|
|
|
<li><a href="./reference.html#const_multi_array_ref"><tt>const_multi_array_ref</tt></a>
|
|
</ol>
|
|
|
|
<tt>multi_array</tt> is a container template. When instantiated, it
|
|
allocates space for the number of elements corresponding to the
|
|
dimensions specified at construction time. A <tt>multi_array</tt> may
|
|
also be default constructed and resized as needed.
|
|
|
|
<p>
|
|
<tt>multi_array_ref</tt> adapts an existing array of data to provide
|
|
the <tt>multi_array</tt> interface. <tt>multi_array_ref</tt> does not own the
|
|
data passed to it.
|
|
|
|
<p>
|
|
<tt>const_multi_array_ref</tt> is similar to <tt>multi_array_ref</tt>
|
|
but guarantees that the contents of the array are immutable. It can
|
|
thus wrap pointers of type <i>T const*</i>.
|
|
|
|
<p>
|
|
The three components exhibit very similar behavior. Aside from
|
|
constructor parameters, <tt>multi_array</tt> and
|
|
<tt>multi_array_ref</tt> export the same interface.
|
|
<tt>const_multi_array_ref</tt> provides only the constness-preserving
|
|
portions of the <tt>multi_array_ref</tt> interface.
|
|
|
|
<a name="sec_assignment"></a>
|
|
<h2>Construction and Assignment</h2>
|
|
<p>Each of the array types -
|
|
<a href="./reference.html#multi_array"><tt>multi_array</tt></a>,
|
|
<a href="./reference.html#multi_array_ref"><tt>multi_array_ref</tt></a>, and
|
|
<a href="./reference.html#const_multi_array_ref"><tt>const_multi_array_ref</tt></a> -
|
|
provides a specialized set of constructors. For further information,
|
|
consult their reference pages.
|
|
|
|
<p>All of the non-const array types in this library provide assignment
|
|
operators<tt>operator=()</tt>. Each of the array types <tt>multi_array</tt>,
|
|
<tt>multi_array_ref</tt>, <tt>subarray</tt>, and
|
|
<tt>array_view</tt> can be assigned from any
|
|
of the others, so long as their shapes match. The
|
|
const variants, <tt>const_multi_array_ref</tt>,
|
|
<tt>const_subarray</tt>, and <tt>const_array_view</tt>, can be the
|
|
source of a copy to an array with matching shape.
|
|
Assignment results in a deep (element by element) copy of the data
|
|
contained within an array.
|
|
|
|
<a name="sec_generators"></a>
|
|
<h2>Array View and Subarray Type Generators</h2>
|
|
In some situations, the use of nested generators for array_view and
|
|
subarray types is inconvenient. For example, inside a
|
|
function template parameterized upon array type, the extra
|
|
"template" keywords can be obfuscating. More likely though, some
|
|
compilers cannot handle templates nested within template parameters.
|
|
For this reason the type generators, <tt>subarray_gen</tt>,
|
|
<tt>const_subarray_gen</tt>, <tt>array_view_gen</tt>, and
|
|
<tt>const_array_view_gen</tt> are provided. Thus, the two typedefs
|
|
in the following example result in the same type:
|
|
<blockquote>
|
|
<pre>
|
|
template <typename Array>
|
|
void my_function() {
|
|
typedef typename Array::template array_view<3>::type view1_t;
|
|
typedef typename boost::array_view_gen<Array,3>::type view2_t;
|
|
// ...
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="sec_dimensions"></a>
|
|
<h2>Specifying Array Dimensions</h2>
|
|
When creating most of the Boost.MultiArray components, it is necessary
|
|
to specify both the number of dimensions and the extent of each
|
|
(<tt>boost::multi_array</tt> also provides a default constructor).
|
|
Though the number of dimensions is always specified as a template
|
|
parameter, two separate mechanisms have been provided to specify the
|
|
extent of each.
|
|
<p>The first method involves passing a
|
|
<a href="../../utility/Collection.html">
|
|
Collection</a> of extents to a
|
|
constructor, most commonly a <tt>boost::array</tt>. The constructor
|
|
will retrieve the beginning iterator from the container and retrieve N
|
|
elements, corresponding to extents for the N dimensions. This is
|
|
useful for writing dimension-independent code.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
boost::array<array_type::index, 3> shape = {{ 3, 4, 2 }};
|
|
array_type A(shape);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>The second method involves passing the constructor an <tt>extent_gen</tt>
|
|
object, specifying the matrix dimensions. The <tt>extent_gen</tt> type
|
|
is defined in the <tt>multi_array_types</tt> namespace and as a
|
|
member of every array type, but by default, the library constructs a
|
|
global <tt>extent_gen</tt> object <tt>boost::extents</tt>. In case of
|
|
concern about memory used by these objects, defining
|
|
<tt>BOOST_MULTI_ARRAY_NO_GENERATORS</tt> before including the library
|
|
header inhibits its construction.
|
|
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
array_type A(boost::extents[3][4][2]);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="sec_access"></a>
|
|
<h2>Accessing Elements</h2>
|
|
The Boost.MultiArray components provide two ways of accessing
|
|
specific elements within a container. The first uses the traditional
|
|
C array notation, provided by <tt>operator[]</tt>.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
array_type A(boost::extents[3][4][2]);
|
|
A[0][0][0] = 3.14;
|
|
assert(A[0][0][0] == 3.14);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p> The second method involves passing a
|
|
<a href="../../utility/Collection.html">
|
|
Collection</a> of indices to <tt>operator()</tt>. N indices will be retrieved
|
|
from the Collection for the N dimensions of the container.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
array_type A(boost::extents[3][4][2]);
|
|
boost::array<array_type::index,3> idx = {{0,0,0}};
|
|
A(idx) = 3.14;
|
|
assert(A(idx) == 3.14);
|
|
</pre>
|
|
</blockquote>
|
|
This can be useful for writing dimension-independent code, and under
|
|
some compilers may yield higher performance than <tt>operator[].</tt>
|
|
|
|
<p>
|
|
By default, both of the above element access methods perform range
|
|
checking. If a supplied index is out of the range defined for an
|
|
array, an assertion will abort the program. To disable range
|
|
checking (for performance reasons in production releases), define
|
|
the <tt>BOOST_DISABLE_ASSERTS</tt> preprocessor macro prior to
|
|
including multi_array.hpp in your application.
|
|
|
|
<a name="sec_views"></a>
|
|
<h2>Creating Views</h2>
|
|
Boost.MultiArray provides the facilities for creating a sub-view of an
|
|
already existing array component. It allows you to create a sub-view that
|
|
retains the same number of dimensions as the original array or one
|
|
that has less dimensions than the original as well.
|
|
|
|
<p>Sub-view creation occurs by placing a call to operator[], passing
|
|
it an <tt>index_gen</tt> type. The <tt>index_gen</tt> is populated by
|
|
passing <tt>index_range</tt> objects to its <tt>operator[]</tt>.
|
|
The <tt>index_range</tt> and <tt>index_gen</tt> types are defined in
|
|
the <tt>multi_array_types</tt> namespace and as nested members of
|
|
every array type. Similar to <tt>boost::extents</tt>, the library by
|
|
default constructs the object <tt>boost::indices</tt>. You can
|
|
suppress this object by
|
|
defining <tt>BOOST_MULTI_ARRAY_NO_GENERATORS</tt> before including the
|
|
library header. A simple sub-view creation example follows.
|
|
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
// myarray = 2 x 3 x 4
|
|
|
|
//
|
|
// array_view dims: [base,bound) (dimension striding default = 1)
|
|
// dim 0: [0,2)
|
|
// dim 1: [1,3)
|
|
// dim 2: [0,4) (strided by 2),
|
|
//
|
|
|
|
typedef boost::multi_array_types::index_range range;
|
|
// OR typedef array_type::index_range range;
|
|
array_type::array_view<3>::type myview =
|
|
myarray[ boost::indices[range(0,2)][range(1,3)][range(0,4,2)] ];
|
|
|
|
for (array_type::index i = 0; i != 2; ++i)
|
|
for (array_type::index j = 0; j != 2; ++j)
|
|
for (array_type::index k = 0; k != 2; ++k)
|
|
assert(myview[i][j][k] == myarray[i][j+1][k*2]);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<p>By passing an integral value to the index_gen, one may create a
|
|
subview with fewer dimensions than the original array component (also
|
|
called slicing).
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
// myarray = 2 x 3 x 4
|
|
|
|
//
|
|
// array_view dims:
|
|
// [base,stride,bound)
|
|
// [0,1,2), 1, [0,2,4)
|
|
//
|
|
|
|
typedef boost::multi_array_types::index_range range;
|
|
array_type::index_gen indices;
|
|
array_type::array_view<2>::type myview =
|
|
myarray[ indices[range(0,2)][1][range(0,4,2)] ];
|
|
|
|
for (array_type::index i = 0; i != 2; ++i)
|
|
for (array_type::index j = 0; j != 2; ++j)
|
|
assert(myview[i][j] == myarray[i][1][j*2]);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<h3>More on <tt>index_range</tt></h3>
|
|
The <tt>index_range</tt> type provides several methods of specifying
|
|
ranges for subview generation. Here are a few range instantiations
|
|
that specify the same range.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
// [base,stride,bound)
|
|
// [0,2,4)
|
|
|
|
typedef boost::multi_array_types::index_range range;
|
|
range a_range;
|
|
a_range = range(0,4,2);
|
|
a_range = range().start(0).finish(4).stride(2);
|
|
a_range = range().start(0).stride(2).finish(4);
|
|
a_range = 0 <= range().stride(2) < 4;
|
|
a_range = 0 <= range().stride(2) <= 3;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
An <tt>index_range</tt> object passed to a slicing operation will
|
|
inherit its start and/or finish value from the array being sliced if
|
|
you do not supply one. This conveniently prevents you from having to
|
|
know the bounds of the array dimension in certain cases. For example,
|
|
the default-constructed range will take the full extent of the
|
|
dimension it is used to specify.
|
|
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array_types::index_range range;
|
|
range a_range;
|
|
|
|
// All elements in this dimension
|
|
a_range = range();
|
|
|
|
// indices i where 3 <= i
|
|
a_range = range().start(3)
|
|
a_range = 3 <= range();
|
|
a_range = 2 < range();
|
|
|
|
// indices i where i < 7
|
|
a_range = range().finish(7)
|
|
a_range = range() < 7;
|
|
a_range = range() <= 6;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The following example slicing operations exhibit some of the
|
|
alternatives shown above
|
|
<blockquote>
|
|
<pre>
|
|
// take all of dimension 1
|
|
// take i < 5 for dimension 2
|
|
// take 4 <= j <= 7 for dimension 3 with stride 2
|
|
myarray[ boost::indices[range()][range() < 5 ][4 <= range().stride(2) <= 7] ];
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<a name="sec_storage"></a>
|
|
<h2>Storage Ordering</h2>
|
|
Each array class provides constructors that accept a storage ordering
|
|
parameter. This is most
|
|
useful when interfacing with legacy codes that require an ordering
|
|
different from standard C, such as FORTRAN. The possibilities are
|
|
<tt>c_storage_order</tt>, <tt>fortran_storage_order</tt>, and
|
|
<tt>general_storage_order</tt>.
|
|
|
|
<p><tt>c_storage_order</tt>, which is the default, will store elements
|
|
in memory in the same order as a C array would, that is, the
|
|
dimensions are stored from last to first.
|
|
|
|
<p><tt>fortran_storage_order</tt> will store elements in memory in the same order
|
|
as FORTRAN would: from the first dimension to
|
|
the last. Note that with use of this parameter, the array
|
|
indices will remain zero-based.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double,3> array_type;
|
|
array_type A(boost::extents[3][4][2],boost::fortran_storage_order());
|
|
call_fortran_function(A.data());
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p><tt>general_storage_order</tt> allows one to customize both the order in
|
|
which dimensions are stored in memory and whether dimensions are
|
|
stored in ascending or descending order.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::general_storage_order<3> storage;
|
|
typedef boost::multi_array<int,3> array_type;
|
|
|
|
// Store last dimension, then first, then middle
|
|
array_type::size_type ordering[] = {2,0,1};
|
|
|
|
// Store the first dimension(dimension 0) in descending order
|
|
bool ascending[] = {false,true,true};
|
|
|
|
array_type A(extents[3][4][2],storage(ordering,ascending));
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<a name="sec_base"></a>
|
|
<h2>Setting The Array Base</h2>
|
|
In some situations, it may be inconvenient or awkward to use an
|
|
array that is zero-based.
|
|
the Boost.MultiArray components provide two facilities for changing the
|
|
bases of an array. One may specify a pair of range values, with
|
|
the <tt>extent_range</tt> type, to
|
|
the <tt>extent_gen</tt> constructor in order to set the base value.
|
|
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
typedef boost::multi_array_types::extent_range range;
|
|
// OR typedef array_type::extent_range range;
|
|
|
|
array_type::extent_gen extents;
|
|
|
|
// dimension 0: 0-based
|
|
// dimension 1: 1-based
|
|
// dimension 2: -1 - based
|
|
array_type A(extents[2][range(1,4)][range(-1,3)]);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
An alternative is to first construct the array normally then
|
|
reset the bases. To set all bases to the same value, use the
|
|
<tt>reindex</tt> member function, passing it a single new index value.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
|
|
array_type::extent_gen extents;
|
|
|
|
array_type A(extents[2][3][4]);
|
|
// change to 1-based
|
|
A.reindex(1)
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
An alternative is to set each base separately using the
|
|
<tt>reindex</tt> member function, passing it a Collection of index bases.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
|
|
array_type::extent_gen extents;
|
|
|
|
// dimension 0: 0-based
|
|
// dimension 1: 1-based
|
|
// dimension 2: (-1)-based
|
|
array_type A(extents[2][3][4]);
|
|
boost::array<array_type::index,ndims> bases = {{0, 1, -1}};
|
|
A.reindex(bases);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<a name="sec_reshape"></a>
|
|
<h2>Changing an Array's Shape</h2>
|
|
The Boost.MultiArray arrays provide a reshape operation. While the
|
|
number of dimensions must remain the same, the shape of the array may
|
|
change so long as the total number of
|
|
elements contained remains the same.
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<double, 3> array_type;
|
|
|
|
array_type::extent_gen extents;
|
|
array_type A(extents[2][3][4]);
|
|
boost::array<array_type::index,ndims> dims = {{4, 3, 2}};
|
|
A.reshape(dims);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<p>
|
|
Note that reshaping an array does not affect the indexing.
|
|
|
|
<a name="sec_resize"></a>
|
|
<h2>Resizing an Array</h2>
|
|
|
|
The <tt>boost::multi_array</tt> class provides an element-preserving
|
|
resize operation. The number of dimensions must remain the same, but
|
|
the extent of each dimension may be increased and decreased as
|
|
desired. When an array is made strictly larger, the existing elements
|
|
will be preserved by copying them into the new underlying memory and
|
|
subsequently destructing the elements in the old underlying memory.
|
|
Any new elements in the array are default constructed. However, if
|
|
the new array size shrinks some of the dimensions, some elements will
|
|
no longer be available.
|
|
|
|
<h3>Example</h3>
|
|
<blockquote>
|
|
<pre>
|
|
typedef boost::multi_array<int, 3> array_type;
|
|
|
|
array_type::extent_gen extents;
|
|
array_type A(extents[3][3][3]);
|
|
A[0][0][0] = 4;
|
|
A[2][2][2] = 5;
|
|
A.resize(extents[2][3][4]);
|
|
assert(A[0][0][0] == 4);
|
|
// A[2][2][2] is no longer valid.
|
|
</pre>
|
|
</blockquote>
|
|
|
|
|
|
<a name="sec_concepts"></a>
|
|
<h2>MultiArray Concept</h2>
|
|
Boost.MultiArray defines and uses the
|
|
<a href="./reference.html#MultiArray">MultiArray</a>
|
|
concept. It specifies an interface for N-dimensional containers.
|
|
|
|
<a name="sec_testcases"></a>
|
|
<h2>Test Cases</h2>
|
|
Boost.MultiArray comes with a suite of test cases meant to exercise
|
|
the features and semantics of the library. A description of the test
|
|
cases can be found <a href="./test_cases.html">here</a>.
|
|
|
|
<a name="sec_related"></a>
|
|
<h2>Related Work</h2>
|
|
|
|
<a href="../../array/index.html">boost::array</a>
|
|
and <a href="https://www.boost.org/sgi/stl/Vector.html">std::vector</a> are
|
|
one-dimensional containers of user data. Both manage their own
|
|
memory. <tt>std::valarray</tt> is a low-level
|
|
C++ Standard Library component
|
|
meant to provide portable high performance for numerical applications.
|
|
<a href="http://www.oonumerics.org/blitz/">Blitz++</a> is
|
|
an array library developed by Todd
|
|
Veldhuizen. It uses
|
|
advanced C++ techniques to provide near-Fortran performance for
|
|
array-based numerical applications.
|
|
<b>array_traits</b> is a beta library, formerly distributed with
|
|
Boost, that provides a means to create iterators over native C++
|
|
arrays.
|
|
|
|
This library is analogous to
|
|
<a href="../../array/index.html">boost::array</a> in that it augments C style N-dimensional
|
|
arrays, as <tt>boost::array</tt> does for C one-dimensional arrays.
|
|
|
|
|
|
<a name="sec_credits"></a>
|
|
<h2>Credits</h2>
|
|
<ul>
|
|
|
|
<li><a href="mailto:garcia@osl.iu.edu">Ronald Garcia</a>
|
|
is the primary author of the library.
|
|
|
|
<li><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>
|
|
helped with the library and provided a sounding board for ideas,
|
|
advice, and assistance porting to Microsoft Visual C++.
|
|
|
|
<li><a href="mailto:gbavestrelli@yahoo.com">Giovanni Bavestrelli</a>
|
|
provided an early implementation of an
|
|
N-dimensional array which inspired feedback from the
|
|
<a href="http://www.boost.org/">Boost</a> mailing list
|
|
members. Some design decisions in this work were based upon this
|
|
implementation and the comments it elicited.
|
|
|
|
<li><a href="mailto:tveldhui@acm.org">Todd Veldhuizen</a> wrote
|
|
<a href="http://oonumerics.org/blitz/">Blitz++</a>, which
|
|
inspired some aspects of this design. In addition, he supplied
|
|
feedback on the design and implementation of the library.
|
|
|
|
<li><a href="mailto:jewillco@osl.iu.edu">Jeremiah Willcock</a>
|
|
provided feedback on the implementation and design of the
|
|
library and some suggestions for features.
|
|
|
|
<li><a href="mailto:bdawes@acm.org">Beman Dawes</a>
|
|
helped immensely with porting the library to Microsoft Windows
|
|
compilers.
|
|
|
|
<li><a href="mailto:glenjofe@gmail.com">Glen Fernandes</a>
|
|
implemented support for the C++11 allocator model, including
|
|
support for stateful allocators, minimal allocators, and
|
|
optimized storage for stateless allocators.
|
|
</ul>
|
|
|
|
<hr>
|
|
|
|
<address>
|
|
<a href="mailto:garcia@.cs.indiana.edu">Ronald Garcia</a>
|
|
</address>
|
|
<!-- Created: Fri Jun 29 10:53:07 EST 2001 -->
|
|
<!-- hhmts start -->Last modified: Tue Feb 7 17:15:50 EST 2006 <!-- hhmts end -->
|
|
|
|
</body>
|
|
</html>
|