Squashed 'third_party/boostorg/multi_array/' content from commit abcb283
Change-Id: I4b93f75f0b15b00216d918bd6db5fc4fcb9c4cc2
git-subtree-dir: third_party/boostorg/multi_array
git-subtree-split: abcb2839d56669d1b5bb8a240ec644f47c66beb2
diff --git a/doc/user.html b/doc/user.html
new file mode 100644
index 0000000..5721128
--- /dev/null
+++ b/doc/user.html
@@ -0,0 +1,675 @@
+<!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="http://www.sgi.com/tech/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.
+</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>