Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linearizer #1039

Merged
merged 7 commits into from
Sep 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@
- *Kernel Package*
- HyperRectDomain can now be empty (lowerBound == upperBound + diagonal(1)). Warning about the use
of lexicographical order in comparison operators of PointVector. (Roland Denis, [#996](https://github.com/DGtal-team/DGtal/pull/996))
- Adds generic linearization (point to index) and reverse process (index to point), specialized for HyperRectDomain.
(Roland Denis, [#1039](https://github.com/DGtal-team/DGtal/pull/1039))

- *Shapes Package*
- Adds a vertex Iterator in the Mesh class in addition to the
Expand Down
111 changes: 2 additions & 109 deletions src/DGtal/images/ImageContainerBySTLVector.ih
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

//////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
#include <DGtal/kernel/domains/Linearizer.h>
//////////////////////////////////////////////////////////////////////////////

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -179,112 +180,6 @@ DGtal::ImageContainerBySTLVector<D, V>::className() const
return "ImageContainerBySTLVector";
}

///////////////////////////////////////////////////////////////////////////////
// Helper classes defined in the compilation unit (anonymous namespace)

namespace
{

/**
* Class template for linearization of the coordinates of a Point.
* This class template is to be specialized for efficiency for dimensions 1,
* 2 and 3 to prevent the use of a loop in these cases.
*
* @tparam Domain an instance of HyperRectDomain
* @tparam dimension domain dimension
*/
template < typename Domain, int dimension>
struct linearizer
{

typedef typename Domain::Point Point;
typedef typename Domain::Size Size;

/**
* Compute the linearized offset of a point in a vector container.
*
* @param aPoint a point
* @param lowerBound lower bound of the image domain.
* @param extent extension of the image domain.
*
* @return the index
*/
static Size apply( const Point & aPoint, const Point & lowerBound,
const Point & extent )
{
Size pos = aPoint[ 0 ] - lowerBound[ 0 ] ;
Size multiplier = 1;
for (typename Domain::Dimension k = 1 ; k < dimension ; ++k)
{
multiplier *= extent[ k-1 ];
pos += multiplier * ( aPoint[ k ] - lowerBound[ k ] );
}
return pos;
}
};

/**
* Specialization of the linearizer class for dimension 1.
*
*/
template < typename Domain >
struct linearizer< Domain, 1 >
{
typedef typename Domain::Point Point;
typedef typename Domain::Size Size;

static Size apply( const Point & aPoint,
const Point & lowerBound,
const Point & /*extent*/ )
{
return aPoint[ 0 ] - lowerBound[ 0 ];
}
};

/**
* Specialization of the linearizer class for dimension 2.
*
*/
template < typename Domain >
struct linearizer< Domain, 2 >
{
typedef typename Domain::Point Point;
typedef typename Domain::Size Size;

static Size apply( const Point & aPoint,
const Point & lowerBound,
const Point & extent )
{
return ( aPoint[ 0 ] - lowerBound[ 0 ] ) + extent[ 0 ] *
(aPoint[ 1 ] - lowerBound[ 1 ] );
}
};

/**
* Specialization of the linearizer class for dimension 3.
*
*/
template < typename Domain >
struct linearizer< Domain, 3 >
{
typedef typename Domain::Point Point;
typedef typename Domain::Size Size;

static Size apply( const Point & aPoint,
const Point & lowerBound,
const Point & extent )
{
Size res = aPoint[ 0 ] - lowerBound[ 0 ];
Size multiplier = extent[ 0 ];
res += multiplier * ( aPoint[ 1 ] - lowerBound[ 1 ] );
multiplier *= extent[ 1 ];
res += multiplier * ( aPoint[ 2 ] - lowerBound[ 2 ] );
return res;
}
};
}



///////////////////////////////////////////////////////////////////////////////
// Internals - private :
Expand All @@ -293,9 +188,7 @@ inline
typename DGtal::ImageContainerBySTLVector<Domain, T>::Size
DGtal::ImageContainerBySTLVector<Domain, T>::linearized(const Point &aPoint) const
{
return linearizer<Domain, Domain::dimension >::apply( aPoint,
myDomain.lowerBound(),
myExtent );
return DGtal::Linearizer<Domain, ColMajorStorage>::getIndex( aPoint, myDomain.lowerBound(), myExtent );
}


Expand Down
8 changes: 4 additions & 4 deletions src/DGtal/kernel/domains/HyperRectDomain_Iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ namespace DGtal
if ( current_pos < TPoint::dimension )
++myPoint[current_pos];
}
while (( current_pos < TPoint::dimension - 1 ) &&
while (( current_pos + 1 < TPoint::dimension ) &&
( myPoint[ current_pos ] > myupper[ current_pos ] ) );
}
}
Expand Down Expand Up @@ -279,7 +279,7 @@ namespace DGtal
if ( current_pos < TPoint::dimension )
--myPoint[ current_pos ];
}
while (( current_pos < TPoint::dimension - 1 ) &&
while (( current_pos + 1 < TPoint::dimension ) &&
( myPoint[ current_pos ] < mylower[ current_pos ] ) );
}
}
Expand Down Expand Up @@ -464,7 +464,7 @@ namespace DGtal
if ( current_pos < mySubDomain.size() )
++myPoint[ mySubDomain[current_pos] ];
}
while (( current_pos < mySubDomain.size() - 1 ) &&
while (( current_pos + 1 < mySubDomain.size() ) &&
( myPoint[ mySubDomain[current_pos] ] >
myupper[ mySubDomain[current_pos] ] ) );
}
Expand Down Expand Up @@ -512,7 +512,7 @@ namespace DGtal
if ( current_pos < mySubDomain.size() )
--myPoint[ mySubDomain[current_pos] ];
}
while (( current_pos < mySubDomain.size() - 1 ) &&
while (( current_pos + 1 < mySubDomain.size() ) &&
( myPoint[ mySubDomain[current_pos] ] <
mylower[ mySubDomain[current_pos] ] ) );
}
Expand Down
191 changes: 191 additions & 0 deletions src/DGtal/kernel/domains/Linearizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
**/

#pragma once

/**
* @file Linearizer.h
* @author Roland Denis (\c [email protected] )
* LAboratory of MAthematics - LAMA (CNRS, UMR 5127), University of Savoie, France
*
* @date 2015/06/18
*
* This file is part of the DGtal library.
*/

#if defined(Linearizer_RECURSES)
#error Recursive header files inclusion detected in Linearizer.h
#else // defined(Linearizer_RECURSES)
/** Prevents recursive inclusion of headers. */
#define Linearizer_RECURSES

#if !defined Linearizer_h
/** Prevents repeated inclusion of headers. */
#define Linearizer_h

//////////////////////////////////////////////////////////////////////////////
// Inclusions
#include <DGtal/kernel/domains/HyperRectDomain.h> // Only for specialization purpose.
//////////////////////////////////////////////////////////////////////////////

namespace DGtal
{

/////////////////////////////////////////////////////////////////////////////

/**
* @brief Tag (empty structure) specifying a row-major storage order.
*
* @see Linearizer
*/
struct RowMajorStorage {};

/**
* @brief Tag (empty structure) specifying a col-major storage order.
*
* @see Linearizer
*/
struct ColMajorStorage {};

/////////////////////////////////////////////////////////////////////////////
/**
* @brief Aim: Linearization and de-linearization interface for domains.
*
* Description of class 'Linearizer' <p>
* This class is empty but there is a specialization for HyperRectDomain.
*
* @tparam TDomain Type of the domain.
* @tparam TStorageOrder Storage Order (RowMajorStorage of ColMajorStorage).
*
*/
template <
typename TDomain,
typename TStorageOrder = ColMajorStorage
>
struct Linearizer;

/**
* @brief Aim: Linearization and de-linearization interface for HyperRectDomain.
*
* This is a static class that provides point linearization (point to index) and de-linearization (index to point) for storages working on HyperRectDomain.
*
* The storage order can be specified by template (default is colum-major ordered).
*
* Example:
* @code
* typedef SpaceND<2> Space;
* tydedef HyperRectDomain<Space> Domain;
* typedef typename Space::Point Point;
*
* const Domain domain( Point(0, 1), Point(4, 3) );
*
* typename Linearizer<Domain>::Size id = Linearizer<Domain>::getIndex( Point(2, 2), domain ); // returns 7.
*
* Point pt = Linearizer<Domain>::getPoint( 7, domain); // returns Point(2,2).
* @endcode
*
* @tparam TSpace Type of the space of the HyperRectDomain (auto-deduced from TDomain template, see Linearizer).
* @tparam TStorageOrder Storage Order (RowMajorStorage of ColMajorStorage).
*/
template <
typename TSpace,
typename TStorageOrder
>
struct Linearizer< HyperRectDomain<TSpace>, TStorageOrder >
{
// Usefull typedefs
typedef HyperRectDomain<TSpace> Domain; ///< The domain type.
typedef typename TSpace::Point Point; ///< The point type.
typedef Point Extent; ///< The domain's extent type.
typedef typename TSpace::Size Size; ///< The space's size type.

/** Linearized index of a point, given the domain lower-bound and extent.
*
* @param[in] aPoint The point to be linearized.
* @param[in] aLowerBound The lower-bound of the domain.
* @param[in] anExtent The extent of the domain.
* @return the linearized index of the point.
*/
static inline
Size getIndex( Point aPoint, Point const& aLowerBound, Extent const& anExtent );

/** Linearized index of a point, given the domain extent.
*
* The lower-bound of the domain is defined to the origin.
*
* @param[in] aPoint The Point to be linearized.
* @param[in] anExtent The extent of the domain.
* @return the linearized index of the point.
*/
static inline
Size getIndex( Point aPoint, Extent const& anExtent );

/** Linearized index of a point, given a domain.
*
* @param[in] aPoint The Point to be linearized.
* @param[in] aDomain The domain.
* @return the linearized index of the point.
*/
static inline
Size getIndex( Point aPoint, Domain const& aDomain );

/** De-linearization of an index, given the domain lower-bound and extent.
*
* @param[in] anIndex The linearized index.
* @param[in] aLowerBound The lower-bound of the domain.
* @param[in] anExtent The domain extent.
* @return the point whose linearized index is anIndex.
*/
static inline
Point getPoint( Size anIndex, Point const& aLowerBound, Extent const& anExtent );

/** De-linearization of an index, given the domain extent.
*
* The lower-bound of the domain is set to the origin.
*
* @param[in] anIndex The linearized index.
* @param[in] anExtent The domain extent.
* @return the point whose linearized index is anIndex.
*/
static inline
Point getPoint( Size anIndex, Extent const& anExtent );

/** De-linearization of an index, given a domain.
*
* @param[in] anIndex The linearized index.
* @param[in] aDomain The domain.
* @return the point whose linearized index is anIndex.
*/
static inline
Point getPoint( Size anIndex, Domain const& aDomain );

}; // end of class Linearizer

} // namespace DGtal


///////////////////////////////////////////////////////////////////////////////
// Includes inline functions.
#include "DGtal/kernel/domains/Linearizer.ih"

// //
///////////////////////////////////////////////////////////////////////////////

#endif // !defined Linearizer_h

#undef Linearizer_RECURSES
#endif // else defined(Linearizer_RECURSES)

Loading