DGtal 1.4.0
Loading...
Searching...
No Matches
AvnaimEtAl2x2DetSignComputer.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 AvnaimEtAl2x2DetSignComputer.ih
19 * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
20 * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21 *
22 * @date 2013/11/19
23 *
24 * Implementation of inline methods defined in AvnaimEtAl2x2DetSignComputer.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <cstdlib>
32//////////////////////////////////////////////////////////////////////////////
33
34///////////////////////////////////////////////////////////////////////////////
35// IMPLEMENTATION of inline methods.
36///////////////////////////////////////////////////////////////////////////////
37
38///////////////////////////////////////////////////////////////////////////////
39// ---------------------------------------------------------------------------
40template <typename T>
41inline
42DGtal::AvnaimEtAl2x2DetSignComputer<T>::AvnaimEtAl2x2DetSignComputer()
43 : myA(NumberTraits<Integer>::ZERO),
44 myB(NumberTraits<Integer>::ZERO),
45 myMax(NumberTraits<Integer>::ONE)
46{
47 //I must compute myMax at runtime because base^exponent
48 //is not equal to std::numeric_limits<Integer>::max()
49 //for non integer type, like float (2^24) or double (2^53)
50 for (unsigned int i = 0; i < (exponent-1); i++)
51 myMax *= base;
52 //I must finish the computation like this, because
53 //the last representable number is base^exponent - 1
54 myMax -= NumberTraits<Integer>::ONE;
55 myMax += (myMax + NumberTraits<Integer>::ONE);
56 ASSERT( myMax > NumberTraits<Integer>::ZERO );
57}
58
59// ---------------------------------------------------------------------------
60template <typename T>
61inline
62void
63DGtal::AvnaimEtAl2x2DetSignComputer<T>::init(const ArgumentInteger& aA, const ArgumentInteger& aB)
64{
65 ASSERT( aA <= myMax );
66 ASSERT( aB <= myMax );
67
68 myA = aA;
69 myB = aB;
70}
71
72// ---------------------------------------------------------------------------
73template <typename T>
74inline
75int
76DGtal::AvnaimEtAl2x2DetSignComputer<T>::quadrant(const Integer& aX, const Integer& aY) const
77{
78 ASSERT( aX != 0 );
79 ASSERT( aY != 0 );
80
81 if (aX > 0)
82 {
83 if (aY > 0)
84 return 0;
85 else
86 return 3;
87 }
88 else
89 {
90 if (aY > 0)
91 return 1;
92 else
93 return 2;
94 }
95}
96
97// ---------------------------------------------------------------------------
98template <typename T>
99inline
100typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::Integer
101DGtal::AvnaimEtAl2x2DetSignComputer<T>::recursiveComputation(const Integer& aA, const Integer& aB,
102 const Integer& aX, const Integer& aY) const
103{
104 // std::cerr << " >>> " << aA << "." << aY << " - " << aB << "." << aX << std::endl;
105 ASSERT( aA > NumberTraits<Integer>::ZERO );
106 ASSERT( aB > NumberTraits<Integer>::ZERO );
107 ASSERT( aX > NumberTraits<Integer>::ZERO );
108 ASSERT( aY > NumberTraits<Integer>::ZERO );
109 ASSERT( aB < aY );
110
111 Integer q = detail::EuclideanDivisionHelper<Integer>::compute(aX, aA);
112 Integer xr = aX - q*aA;
113 // std::cout << " >>> xr= " << xr;
114
115 if (aB > ( myMax / q)) {
116 return -NumberTraits<Integer>::ONE;
117 } else {
118 if (xr == NumberTraits<Integer>::ZERO) {
119 Integer qb = q * aB;
120 if (aY > qb) {
121 return NumberTraits<Integer>::ONE;
122 } else if (aY < qb) {
123 return -NumberTraits<Integer>::ONE;
124 } else { //(aY == qb)
125 return NumberTraits<Integer>::ZERO;
126 }
127 } else {
128 Integer yr = aY - q * aB;
129 // std::cout << ", yr= " << yr << std::endl;
130
131 if (yr <= NumberTraits<Integer>::ZERO)
132 return -NumberTraits<Integer>::ONE;
133 if (yr >= aB)
134 return NumberTraits<Integer>::ONE;
135
136 if (2*xr < aA) {
137 if (2*yr >= aB) {
138 return NumberTraits<Integer>::ONE;
139 } else { //(2*yr < aB)
140 return computation(aA, aB, xr, yr);
141 }
142 } else if (2*xr > aA) {
143 if (2*yr <= aB) {
144 return -NumberTraits<Integer>::ONE;
145 } else { //(2*yr > aB)
146 return -computation(aA, aB, (aA-xr), (aB-yr));
147 }
148 } else { //(2*xr == aA)
149 if (2*yr == aB) {
150 return NumberTraits<Integer>::ZERO;
151 } else if (2*yr < aB) {
152 return -NumberTraits<Integer>::ONE;
153 } else { //(2*yr > aB)
154 return NumberTraits<Integer>::ONE;
155 }
156 }
157 }
158 }
159
160
161
162}
163
164// ---------------------------------------------------------------------------
165template <typename T>
166inline
167typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::Integer
168DGtal::AvnaimEtAl2x2DetSignComputer<T>::computation(const Integer& aA, const Integer& aB,
169 const Integer& aX, const Integer& aY) const
170{
171 // std::cerr << " >>> " << aA << "." << aY << " - " << aB << "." << aX << std::endl;
172 ASSERT( aA > NumberTraits<Integer>::ZERO );
173 ASSERT( aB > NumberTraits<Integer>::ZERO );
174 ASSERT( aX > NumberTraits<Integer>::ZERO );
175 ASSERT( aY > NumberTraits<Integer>::ZERO );
176
177 if (aA == aX) {
178 if (aB == aY) {
179 return NumberTraits<Integer>::ZERO;
180 } else if (aB < aY) {
181 return NumberTraits<Integer>::ONE;
182 } else { //(aB > aY)
183 return -NumberTraits<Integer>::ONE;
184 }
185 } else if (aA < aX) {
186 if (aB >= aY) {
187 return -NumberTraits<Integer>::ONE;
188 } else { //(aB < aY)
189 return recursiveComputation(aA, aB, aX, aY);
190 }
191 } else { //(aA > aX)
192 if (aB <= aY) {
193 return NumberTraits<Integer>::ONE;
194 } else { //(aB > aY)
195 return -recursiveComputation(aX, aY, aA, aB);
196 }
197 }
198}
199
200// ---------------------------------------------------------------------------
201template <typename T>
202inline
203typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::ResultInteger
204DGtal::AvnaimEtAl2x2DetSignComputer<T>::operator()(const ArgumentInteger& aX, const ArgumentInteger& aY) const
205{
206 ASSERT( aX <= myMax );
207 ASSERT( aY <= myMax );
208
209 // zeros
210 if ( (myA == NumberTraits<Integer>::ZERO) || (aY == NumberTraits<Integer>::ZERO) ) {
211 if ( (aX == NumberTraits<Integer>::ZERO) || (myB == NumberTraits<Integer>::ZERO) ) {
212 return NumberTraits<Integer>::ZERO;
213 } else {
214 ASSERT( aX != NumberTraits<Integer>::ZERO );
215 ASSERT( myB != NumberTraits<Integer>::ZERO );
216 if (myB < NumberTraits<Integer>::ZERO) {
217 if (aX < NumberTraits<Integer>::ZERO)
218 return -NumberTraits<Integer>::ONE;
219 else
220 return NumberTraits<Integer>::ONE;
221 } else {
222 if (aX < NumberTraits<Integer>::ZERO)
223 return NumberTraits<Integer>::ONE;
224 else
225 return -NumberTraits<Integer>::ONE;
226 }
227 }
228 } else if ( (aX == NumberTraits<Integer>::ZERO) || (myB == NumberTraits<Integer>::ZERO) ) {
229 ASSERT( myA != NumberTraits<Integer>::ZERO );
230 ASSERT( aY != NumberTraits<Integer>::ZERO );
231 if (aY < NumberTraits<Integer>::ZERO) {
232 if (myA < NumberTraits<Integer>::ZERO) return NumberTraits<Integer>::ONE;
233 else return -NumberTraits<Integer>::ONE;
234 } else {
235 if (myA < NumberTraits<Integer>::ZERO) return -NumberTraits<Integer>::ONE;
236 else return NumberTraits<Integer>::ONE;
237 }
238 } else {
239 // quadrants
240 int qab = quadrant(myA, myB);
241 int qxy = quadrant(aX, aY);
242 // std::cerr << " >>> quadrants " << qab << ", " << qxy << std::endl;
243
244 switch (qab)
245 {
246 case 0:
247 switch (qxy)
248 {
249 case 0:
250 return computation(myA, myB, aX, aY);
251 case 1:
252 return NumberTraits<Integer>::ONE;
253 case 2:
254 return -computation(myA, myB, -aX, -aY);
255 case 3:
256 return -NumberTraits<Integer>::ONE;
257 default:
258 FATAL_ERROR( false );
259 return NumberTraits<Integer>::ZERO;
260 }
261 break;
262 case 1:
263 switch (qxy)
264 {
265 case 0:
266 return -NumberTraits<Integer>::ONE;
267 case 1:
268 return -computation(-myA, myB, -aX, aY);
269 case 2:
270 return NumberTraits<Integer>::ONE;
271 case 3:
272 return computation(-myA, myB, aX, -aY);
273 default:
274 FATAL_ERROR( false );
275 return NumberTraits<Integer>::ZERO;
276 }
277 break;
278 case 2:
279 switch (qxy)
280 {
281 case 0:
282 return -computation(-myA, -myB, aX, aY);
283 case 1:
284 return -NumberTraits<Integer>::ONE;
285 case 2:
286 return computation(-myA, -myB, -aX, -aY);
287 case 3:
288 return NumberTraits<Integer>::ONE;
289 default:
290 FATAL_ERROR( false );
291 return NumberTraits<Integer>::ZERO;
292 }
293 break;
294 case 3:
295 switch (qxy)
296 {
297 case 0:
298 return NumberTraits<Integer>::ONE;
299 case 1:
300 return computation(myA, -myB, -aX, aY);
301 case 2:
302 return -NumberTraits<Integer>::ONE;
303 case 3:
304 return -computation(myA, -myB, aX, -aY);
305 default:
306 FATAL_ERROR( false );
307 return NumberTraits<Integer>::ZERO;
308 }
309 break;
310 default:
311 FATAL_ERROR( false );
312 return NumberTraits<Integer>::ZERO;
313 }
314 }
315}
316
317// ---------------------------------------------------------------------------
318template <typename T>
319inline
320typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::ResultInteger
321DGtal::AvnaimEtAl2x2DetSignComputer<T>::operator()(const ArgumentInteger& aA, const ArgumentInteger& aB,
322 const ArgumentInteger& aX, const ArgumentInteger& aY)
323{
324 ASSERT( aA <= myMax );
325 ASSERT( aB <= myMax );
326 init(aA,aB);
327
328 ASSERT( aX <= myMax );
329 ASSERT( aY <= myMax );
330 return operator()(aX, aY);
331}
332
333// ----------------------------------------------------------------------------
334template <typename T>
335inline
336void
337DGtal::AvnaimEtAl2x2DetSignComputer<T>::selfDisplay ( std::ostream & out ) const
338{
339 out << "[AvnaimEtAl2x2DetSignComputer]";
340}
341
342// ----------------------------------------------------------------------------
343template <typename T>
344inline
345bool
346DGtal::AvnaimEtAl2x2DetSignComputer<T>::isValid() const
347{
348 return true;
349}
350
351///////////////////////////////////////////////////////////////////////////////
352// Implementation of inline functions //
353
354template <typename T>
355inline
356std::ostream&
357DGtal::operator<< ( std::ostream & out,
358 const AvnaimEtAl2x2DetSignComputer<T> & object )
359{
360 object.selfDisplay( out );
361 return out;
362}
363
364// //
365///////////////////////////////////////////////////////////////////////////////
366
367