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// ---------------------------------------------------------------------------
 
   42DGtal::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// ---------------------------------------------------------------------------
 
   63DGtal::AvnaimEtAl2x2DetSignComputer<T>::init(const ArgumentInteger& aA, const ArgumentInteger& aB)
 
   65  ASSERT( aA <= myMax ); 
 
   66  ASSERT( aB <= myMax ); 
 
   72// ---------------------------------------------------------------------------
 
   76DGtal::AvnaimEtAl2x2DetSignComputer<T>::quadrant(const Integer& aX, const Integer& aY) const
 
   97// ---------------------------------------------------------------------------
 
  100typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::Integer
 
  101DGtal::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// ---------------------------------------------------------------------------
 
  167typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::Integer
 
  168DGtal::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// ---------------------------------------------------------------------------
 
  203typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::ResultInteger
 
  204DGtal::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// ---------------------------------------------------------------------------
 
  320typename DGtal::AvnaimEtAl2x2DetSignComputer<T>::ResultInteger
 
  321DGtal::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// ----------------------------------------------------------------------------
 
  337DGtal::AvnaimEtAl2x2DetSignComputer<T>::selfDisplay ( std::ostream & out ) const
 
  339  out << "[AvnaimEtAl2x2DetSignComputer]";
 
  342// ----------------------------------------------------------------------------
 
  346DGtal::AvnaimEtAl2x2DetSignComputer<T>::isValid() const
 
  351///////////////////////////////////////////////////////////////////////////////
 
  352// Implementation of inline functions                                        //
 
  357DGtal::operator<< ( std::ostream & out, 
 
  358                    const AvnaimEtAl2x2DetSignComputer<T> & object )
 
  360  object.selfDisplay( out );
 
  365///////////////////////////////////////////////////////////////////////////////