#ifndef NDIM_ARRAY_ACCESS_H
#define NDIM_ARRAY_ACCESS_H

/**
 * \file  ndim_array_index.h
 *
 *  Provides functions to convert a linear array index into a
 *  n-dimensional position in an base^n sized n-cube and vice versa.
 */


/***********************************************************************\
 *    Includes                                                         *
\***********************************************************************/
#include <stdint.h>


/***********************************************************************\
 *    Definitions of exported functions                                * 
\***********************************************************************/
/**
 * \brief  Converts an n-dimensional index of a base^n array into a
 *         linear index.
 *
 * The mapping works in the following way:
 * linear_index = sum_i ndim_index[i] * base^i
 *
 * E.g. for a base-3 2-dimensional array:
 * ndim_index[0]  ndim_index[1]   return value
 *      0              0               0
 *      1              0               1
 *      2              0               2
 *      0              1               3
 *      1              1               4
 *      2              1               5
 *      0              2               6
 *      1              2               7
 *      2              2               8
 *
 * \param  n           The dimensionality.
 * \param  base        The size of the array in one dimension (the total
 *                     length of the array is base^n).
 * \param  offset      That is the value that needs to be substracted
 *                     from each ndim_index[i] so that they are in the
 *                     range [0,base-1].
 * \param  ndim_index
 *
 * \return  Returns the linear index that corresponds to the given
 *          n-dimensional index.
 */
extern uint32_t
ndim_array_access_n2lin(uint32_t n,
                        uint32_t base,
                        uint32_t offset,
                        const uint32_t *ndim_index);

/**
 * \brief  Converts a linear index into an n-dimensional index into a
 *         base^n array.
 *
 *  This function will convert a given linear index to the according
 *  array index.  This subsitutes something like array[3][2][5] into a
 *  linear index array[linear_index].  It is defined in such a way, that
 *  ndim_index[n-1] will refer to the fastest varying index.
 *
 *  E.g. a base-3 2-dimensional array is mapped in the following way
 *  into a linear index:
 *  linear_index  ndim_index[0]  ndim_index[1]
 *       0             0              0
 *       1             1              0
 *       2             2              0
 *       3             0              1
 *       4             1              1
 *       5             2              1
 *       6             0              2
 *       7             1              2
 *       8             2              2
 *
 * \param  n             The dimensionality.
 * \param  linear_index  The linear index that should be converted to an
 *                       array index.
 * \param  base          The size of the array in one dimension.
 * \param  offset        An additional factor that will be added to each
 *                       array index.
 * \param  *ndim_index   The external array of at least size n that will
 *                       hold the array index.
 *
 * \return  Returns nothing.
 */
extern void
ndim_array_access_lin2n(uint32_t n,
                        uint32_t linear_index,
                        uint32_t base,
                        uint32_t offset,
                        uint32_t *ndim_index);


#endif /* NDIM_ARRAY_ACCESS_H */
