DGtal 1.3.0
Loading...
Searching...
No Matches
Linearizer.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/**
18 * @file Linearizer.ih
19 * @author Roland Denis (\c roland.denis@univ-smb.fr )
20 * LAboratory of MAthematics - LAMA (CNRS, UMR 5127), University of Savoie, France
21 *
22 * @date 2015/06/18
23 *
24 * This file is part of the DGtal library.
25 */
26
27
28//////////////////////////////////////////////////////////////////////////////
29#include <cstddef>
30//////////////////////////////////////////////////////////////////////////////
31
32///////////////////////////////////////////////////////////////////////////////
33// IMPLEMENTATION of inline methods.
34///////////////////////////////////////////////////////////////////////////////
35
36namespace DGtal
37{
38
39 /// Tools
40 namespace
41 {
42
43 /** Helper that calculates the dimension index given the current linearization step.
44 *
45 * The step I is always decrementing from N-1 to 0.
46 *
47 * @tparam TStorageOrder Storage order (RowMajorStorage of ColMajorStorage).
48 * @tparam N Dimension of the space.
49 * @tparam I Current step.
50 */
51 template < typename TStorageOrder, std::size_t N, std::size_t I >
52 struct linearizer_helper;
53
54 template < std::size_t N, std::size_t I >
55 struct linearizer_helper< RowMajorStorage, N, I >
56 {
57 enum { dim = I }; ///< Dimension index related to the step I.
58 };
59
60 template < std::size_t N, std::size_t I >
61 struct linearizer_helper< ColMajorStorage, N, I >
62 {
63 enum { dim = N-1 - I }; ///< Dimension index related to the step I.
64 };
65
66 /** Templated static structure for linearization of the coordinates of a point.
67 *
68 * @tparam TSize Type of the linearizared index.
69 * @tparam TStorageOrder Storage order (RowMajorStorage of ColMajorStorage).
70 * @tparam N Dimension of the space.
71 * @tparam I Current step.
72 */
73 template < typename TSize, typename TStorageOrder, std::size_t N, std::size_t I = N-1 >
74 struct linearizer_impl
75 {
76
77 /**
78 * Return the linearized index from the coordinates of a point.
79 *
80 * @tparam TPoint Type of the point.
81 * @tparam TExtent Type of the domain's extent.
82 * @param[in] aPoint The point to linearize.
83 * @param[in] anExtent The extent of the domain.
84 * @return the linearized index of the point.
85 */
86 template < typename TPoint, typename TExtent >
87 static inline
88 TSize apply( TPoint const& aPoint, TExtent const& anExtent )
89 {
90 return
91 aPoint[ linearizer_helper<TStorageOrder, N, I>::dim ]
92 + anExtent[ linearizer_helper<TStorageOrder, N, I>::dim ] * linearizer_impl< TSize, TStorageOrder, N, I-1 >::apply( aPoint, anExtent );
93 }
94 };
95
96 /**
97 * Specialization of the structure linearizer_impl for the last step.
98 *
99 * It is actually used as a terminate condition of the recursive process.
100 */
101 template < typename TSize, typename TStorageOrder, std::size_t N >
102 struct linearizer_impl< TSize, TStorageOrder, N, 0 >
103 {
104 template < typename TPoint, typename TExtent >
105 static inline
106 TSize apply( TPoint const& aPoint, TExtent const& /* anExtent */ )
107 {
108 return aPoint[ linearizer_helper<TStorageOrder, N, 0>::dim ];
109 }
110 };
111
112 /** Templated static structure for de-linearization of a point index.
113 *
114 * @tparam TStorageOrder Storage order (RowMajorStorage of ColMajorStorage).
115 * @tparam N Dimension of the space.
116 * @tparam I Current step.
117 */
118 template < typename TStorageOrder, std::size_t N, std::size_t I = N-1 >
119 struct delinearizer_impl
120 {
121
122 /**
123 * Return the de-linearized point from the linearized index of the point.
124 *
125 * @tparam TPoint Type of the point.
126 * @tparam TExtent Type of the domain's extent.
127 * @tparam TSize Type of the linearized index.
128 * @param[out] aPoint The point after de-linearization.
129 * @param[in] anExtent The extent of the domain.
130 * @param[in] anIndex The linearized index of the point.
131 */
132 template < typename TPoint, typename TExtent, typename TSize >
133 static inline
134 void apply( TPoint& aPoint, TExtent const& anExtent, TSize anIndex )
135 {
136 typename TExtent::Scalar const dim_extent = anExtent[ linearizer_helper<TStorageOrder, N, I>::dim ];
137 aPoint[ linearizer_helper<TStorageOrder, N, I>::dim ] = anIndex % dim_extent;
138 delinearizer_impl< TStorageOrder, N, I-1 >::apply( aPoint, anExtent, anIndex / dim_extent );
139 }
140 };
141
142 /**
143 * Specialization of the structure delinearizer_impl for the last step.
144 *
145 * It is actually used as a terminate condition of the recursive process.
146 */
147 template < typename TStorageOrder, std::size_t N >
148 struct delinearizer_impl< TStorageOrder, N, 0 >
149 {
150 template < typename TPoint, typename TExtent, typename TSize >
151 static inline
152 void apply( TPoint& aPoint, TExtent const& /* anExtent */, TSize anIndex )
153 {
154 aPoint[ linearizer_helper<TStorageOrder, N, 0>::dim ] = anIndex;
155 }
156 };
157
158 } // anonymous namespace
159
160 /// Linearized index of a point, given the domain lower-bound and extent.
161 template <typename TSpace, typename TStorageOrder>
162 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Size
163 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
164 getIndex( Point aPoint, Point const& aLowerBound, Extent const& anExtent )
165 {
166 aPoint -= aLowerBound;
167 return linearizer_impl<Size, TStorageOrder, Domain::dimension>::apply(aPoint, anExtent);
168 }
169
170 /// Linearized index of a point, given the domain extent.
171 template <typename TSpace, typename TStorageOrder>
172 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Size
173 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
174 getIndex( Point aPoint, Extent const& anExtent )
175 {
176 return linearizer_impl<Size, TStorageOrder, Domain::dimension>::apply(aPoint, anExtent);
177 }
178
179 /// Linearized index of a point, given a domain.
180 template <typename TSpace, typename TStorageOrder>
181 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Size
182 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
183 getIndex( Point aPoint, Domain const& aDomain )
184 {
185 return linearizer_impl<Size, TStorageOrder, Domain::dimension>::apply(aPoint - aDomain.lowerBound(), aDomain.upperBound()-aDomain.lowerBound()+Point::diagonal(1));
186 }
187
188 /// De-linearization of an index, given the domain lower-bound and extent.
189 template <typename TSpace, typename TStorageOrder>
190 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Point
191 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
192 getPoint( Size anIndex, Point const& aLowerBound, Extent const& anExtent )
193 {
194 Point point;
195 delinearizer_impl<TStorageOrder, Domain::dimension>::apply(point, anExtent, anIndex);
196 return point + aLowerBound;
197 }
198
199 /// De-linearization of an index, given the domain extent.
200 template <typename TSpace, typename TStorageOrder>
201 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Point
202 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
203 getPoint( Size anIndex, Extent const& anExtent )
204 {
205 Point point;
206 delinearizer_impl<TStorageOrder, Domain::dimension>::apply(point, anExtent, anIndex);
207 return point;
208 }
209
210 /// De-linearization of an index, given a domain.
211 template <typename TSpace, typename TStorageOrder>
212 typename Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::Point
213 Linearizer< HyperRectDomain<TSpace>, TStorageOrder >::
214 getPoint( Size anIndex, Domain const& aDomain )
215 {
216 Point point;
217 delinearizer_impl<TStorageOrder, Domain::dimension>::apply(point, aDomain.upperBound()-aDomain.lowerBound()+Point::diagonal(1), anIndex);
218 return point + aDomain.lowerBound();
219 }
220
221} // namespace DGtal
222