namespace Eigen {

/** \page TutorialMapClass Tutorial page 10 - Interfacing with C/C++ arrays and external libraries: the %Map class

\ingroup Tutorial

\li \b Previous: \ref TutorialSparse
\li \b Next:

This tutorial page explains how to work with "raw" C++ arrays.  This can be useful in a variety of contexts, particularly when "importing" vectors and matrices from other libraries into Eigen.

\b Table \b of \b contents
  - \ref TutorialMapIntroduction
  - \ref TutorialMapTypes
  - \ref TutorialMapUsing
  - \ref TutorialMapPlacementNew

\section TutorialMapIntroduction Introduction

Occasionally you may have a pre-defined array of numbers that you want to use within Eigen as a vector or matrix. While one option is to make a copy of the data, most commonly you probably want to re-use this memory as an Eigen type. Fortunately, this is very easy with the Map class.

\section TutorialMapTypes Map types and declaring Map variables

A Map object has a type defined by its Eigen equivalent:
\code
Map<Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> >
\endcode
Note that, in this default case, a Map requires just a single template parameter.  

To construct a Map variable, you need two other pieces of information: a pointer to the region of memory defining the array of coefficients, and the desired shape of the matrix or vector.  For example, to define a matrix of \c float with sizes determined at compile time, you might do the following:
\code
Map<MatrixXf> mf(pf,rows,columns);
\endcode
where \c pf is a \c float \c * pointing to the array of memory.  A fixed-size read-only vector of integers might be declared as
\code
Map<const Vector4i> mi(pi);
\endcode
where \c pi is an \c int \c *. In this case the size does not have to be passed to the constructor, because it is already specified by the Matrix/Array type.

Note that Map does not have a default constructor; you \em must pass a pointer to intialize the object. However, you can work around this requirement (see \ref TutorialMapPlacementNew).

Map is flexible enough to accomodate a variety of different data representations.  There are two other (optional) template parameters:
\code
Map<typename MatrixType,
    int MapOptions,
    typename StrideType>
\endcode
\li \c MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned.  The default is \c #Unaligned.
\li \c StrideType allows you to specify a custom layout for the memory array, using the Stride class.  One example would be to specify that the data array is organized in row-major format:
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr>
<td>\include Tutorial_Map_rowmajor.cpp </td>
<td>\verbinclude Tutorial_Map_rowmajor.out </td>
</table>
However, Stride is even more flexible than this; for details, see the documentation for the Map and Stride classes.

\section TutorialMapUsing Using Map variables

You can use a Map object just like any other Eigen type:
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr>
<td>\include Tutorial_Map_using.cpp </td>
<td>\verbinclude Tutorial_Map_using.out </td>
</table>

However, when writing functions taking Eigen types, it is important to realize that a Map type is \em not identical to its Dense equivalent.  See \ref TopicFunctionTakingEigenTypesMultiarguments for details.

\section TutorialMapPlacementNew Changing the mapped array

It is possible to change the array of a Map object after declaration, using the C++ "placement new" syntax:
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr>
<td>\include Map_placement_new.cpp </td>
<td>\verbinclude Map_placement_new.out </td>
</table>
Despite appearances, this does not invoke the memory allocator, because the syntax specifies the location for storing the result.

This syntax makes it possible to declare a Map object without first knowing the mapped array's location in memory:
\code
Map<Matrix3f> A(NULL);  // don't try to use this matrix yet!
VectorXf b(n_matrices);
for (int i = 0; i < n_matrices; i++)
{
  new (&A) Map<Matrix3f>(get_matrix_pointer(i));
  b(i) = A.trace();
}
\endcode

\li \b Next:

*/

}
