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.
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.
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/>.
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
24 * Implementation of inline methods defined in AvnaimEtAl2x2DetSignComputer.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 //////////////////////////////////////////////////////////////////////////////
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
38 ///////////////////////////////////////////////////////////////////////////////
39 // ---------------------------------------------------------------------------
42 DGtal::AvnaimEtAl2x2DetSignComputer<T>::AvnaimEtAl2x2DetSignComputer()
43 : myA(NumberTraits<Integer>::ZERO),
44 myB(NumberTraits<Integer>::ZERO),
45 myMax(NumberTraits<Integer>::ONE)
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++)
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 );
59 // ---------------------------------------------------------------------------
63 DGtal::AvnaimEtAl2x2DetSignComputer<T>::init(const ArgumentInteger& aA, const ArgumentInteger& aB)
65 ASSERT( aA <= myMax );
66 ASSERT( aB <= myMax );
72 // ---------------------------------------------------------------------------
76 DGtal::AvnaimEtAl2x2DetSignComputer<T>::quadrant(const Integer& aX, const Integer& aY) const
97 // ---------------------------------------------------------------------------
100 typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::Integer
101 DGtal::AvnaimEtAl2x2DetSignComputer<T>::recursiveComputation(const Integer& aA, const Integer& aB,
102 const Integer& aX, const Integer& aY) const
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 );
111 Integer q = detail::EuclideanDivisionHelper<Integer>::compute(aX, aA);
112 Integer xr = aX - q*aA;
113 // std::cout << " >>> xr= " << xr;
115 if (aB > ( myMax / q)) {
116 return -NumberTraits<Integer>::ONE;
118 if (xr == NumberTraits<Integer>::ZERO) {
121 return NumberTraits<Integer>::ONE;
122 } else if (aY < qb) {
123 return -NumberTraits<Integer>::ONE;
124 } else { //(aY == qb)
125 return NumberTraits<Integer>::ZERO;
128 Integer yr = aY - q * aB;
129 // std::cout << ", yr= " << yr << std::endl;
131 if (yr <= NumberTraits<Integer>::ZERO)
132 return -NumberTraits<Integer>::ONE;
134 return NumberTraits<Integer>::ONE;
138 return NumberTraits<Integer>::ONE;
139 } else { //(2*yr < aB)
140 return computation(aA, aB, xr, yr);
142 } else if (2*xr > aA) {
144 return -NumberTraits<Integer>::ONE;
145 } else { //(2*yr > aB)
146 return -computation(aA, aB, (aA-xr), (aB-yr));
148 } else { //(2*xr == aA)
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;
164 // ---------------------------------------------------------------------------
165 template <typename T>
167 typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::Integer
168 DGtal::AvnaimEtAl2x2DetSignComputer<T>::computation(const Integer& aA, const Integer& aB,
169 const Integer& aX, const Integer& aY) const
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 );
179 return NumberTraits<Integer>::ZERO;
180 } else if (aB < aY) {
181 return NumberTraits<Integer>::ONE;
183 return -NumberTraits<Integer>::ONE;
185 } else if (aA < aX) {
187 return -NumberTraits<Integer>::ONE;
189 return recursiveComputation(aA, aB, aX, aY);
193 return NumberTraits<Integer>::ONE;
195 return -recursiveComputation(aX, aY, aA, aB);
200 // ---------------------------------------------------------------------------
201 template <typename T>
203 typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::ResultInteger
204 DGtal::AvnaimEtAl2x2DetSignComputer<T>::operator()(const ArgumentInteger& aX, const ArgumentInteger& aY) const
206 ASSERT( aX <= myMax );
207 ASSERT( aY <= myMax );
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;
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;
220 return NumberTraits<Integer>::ONE;
222 if (aX < NumberTraits<Integer>::ZERO)
223 return NumberTraits<Integer>::ONE;
225 return -NumberTraits<Integer>::ONE;
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;
235 if (myA < NumberTraits<Integer>::ZERO) return -NumberTraits<Integer>::ONE;
236 else return NumberTraits<Integer>::ONE;
240 int qab = quadrant(myA, myB);
241 int qxy = quadrant(aX, aY);
242 // std::cerr << " >>> quadrants " << qab << ", " << qxy << std::endl;
250 return computation(myA, myB, aX, aY);
252 return NumberTraits<Integer>::ONE;
254 return -computation(myA, myB, -aX, -aY);
256 return -NumberTraits<Integer>::ONE;
258 FATAL_ERROR( false );
259 return NumberTraits<Integer>::ZERO;
266 return -NumberTraits<Integer>::ONE;
268 return -computation(-myA, myB, -aX, aY);
270 return NumberTraits<Integer>::ONE;
272 return computation(-myA, myB, aX, -aY);
274 FATAL_ERROR( false );
275 return NumberTraits<Integer>::ZERO;
282 return -computation(-myA, -myB, aX, aY);
284 return -NumberTraits<Integer>::ONE;
286 return computation(-myA, -myB, -aX, -aY);
288 return NumberTraits<Integer>::ONE;
290 FATAL_ERROR( false );
291 return NumberTraits<Integer>::ZERO;
298 return NumberTraits<Integer>::ONE;
300 return computation(myA, -myB, -aX, aY);
302 return -NumberTraits<Integer>::ONE;
304 return -computation(myA, -myB, aX, -aY);
306 FATAL_ERROR( false );
307 return NumberTraits<Integer>::ZERO;
311 FATAL_ERROR( false );
312 return NumberTraits<Integer>::ZERO;
317 // ---------------------------------------------------------------------------
318 template <typename T>
320 typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::ResultInteger
321 DGtal::AvnaimEtAl2x2DetSignComputer<T>::operator()(const ArgumentInteger& aA, const ArgumentInteger& aB,
322 const ArgumentInteger& aX, const ArgumentInteger& aY)
324 ASSERT( aA <= myMax );
325 ASSERT( aB <= myMax );
328 ASSERT( aX <= myMax );
329 ASSERT( aY <= myMax );
330 return operator()(aX, aY);
333 // ----------------------------------------------------------------------------
334 template <typename T>
337 DGtal::AvnaimEtAl2x2DetSignComputer<T>::selfDisplay ( std::ostream & out ) const
339 out << "[AvnaimEtAl2x2DetSignComputer]";
342 // ----------------------------------------------------------------------------
343 template <typename T>
346 DGtal::AvnaimEtAl2x2DetSignComputer<T>::isValid() const
351 ///////////////////////////////////////////////////////////////////////////////
352 // Implementation of inline functions //
354 template <typename T>
357 DGtal::operator<< ( std::ostream & out,
358 const AvnaimEtAl2x2DetSignComputer<T> & object )
360 object.selfDisplay( out );
365 ///////////////////////////////////////////////////////////////////////////////