Commit 1d80e038 authored by Sylvain Lombardy's avatar Sylvain Lombardy Committed by Alexandre Duret-Lutz
Browse files

Fix implementation of proper() for Q.

* include/vaucanson/algebra/implementation/semiring/q_number.hh,
include/vaucanson/algebra/implementation/semiring/q_number.hxx,
include/vaucanson/algorithms/eps_removal.hxx,
include/vaucanson/misc/algebra.hh,
include/vaucanson/misc/algebra.hxx: Here.
parent 0b26bdc0
2011-09-13 Sylvain Lombardy <lombardy@univ-mlv.fr>
Fix implementation of proper() for Q.
* include/vaucanson/algebra/implementation/semiring/q_number.hh,
include/vaucanson/algebra/implementation/semiring/q_number.hxx,
include/vaucanson/algorithms/eps_removal.hxx,
include/vaucanson/misc/algebra.hh,
include/vaucanson/misc/algebra.hxx: Here.
2011-09-13 Sylvain Lombardy <lombardy@univ-mlv.fr>
 
Fix image and domain.
......
......@@ -54,7 +54,7 @@ namespace vcsn
* @author David Moreira <david.moreira@epita.fr>
*/
template<typename NUMType, typename DENType>
template<typename IntType>
class TRationalNumber
{
public:
......@@ -65,13 +65,13 @@ namespace vcsn
TRationalNumber ();
/// Constructor define numerator. Denominator set at 1.
inline
TRationalNumber (const NUMType num);
TRationalNumber (const IntType num);
/// Constructor define numerator and denominator.
inline
TRationalNumber (const NUMType num, const DENType den);
TRationalNumber (const IntType num, const IntType den);
/// Copy Constructor
inline
TRationalNumber (const TRationalNumber<NUMType, DENType>& nb);
TRationalNumber (const TRationalNumber<IntType>& nb);
// Object destructor.
inline
~TRationalNumber ();
......@@ -81,16 +81,16 @@ namespace vcsn
/// @{
/// Set the numerator and the denominator.
inline
TRationalNumber& set (const NUMType num, const DENType den = 1);
TRationalNumber& set (const IntType num, const IntType den = 1);
/// @}
/// @name Accessors
/// @{
/// Get the numerator.
inline
NUMType num_get () const;
IntType num_get () const;
/// Get the denominator.
inline
DENType den_get () const;
IntType den_get () const;
/// Printing method.
inline
std::ostream& print (std::ostream& ostr) const;
......@@ -101,50 +101,52 @@ namespace vcsn
/// @{
/// Usual Arithemetics Operator.
inline
TRationalNumber<NUMType, DENType> operator+ (const TRationalNumber<NUMType, DENType>& nb) const;
TRationalNumber<IntType> operator+ (const TRationalNumber<IntType>& nb) const;
inline
TRationalNumber<NUMType, DENType> operator- (const TRationalNumber<NUMType, DENType>& nb) const;
TRationalNumber<IntType> operator- (const TRationalNumber<IntType>& nb) const;
inline
TRationalNumber<NUMType, DENType> operator- () const;
TRationalNumber<IntType> operator- () const;
inline
TRationalNumber<NUMType, DENType> operator* (const TRationalNumber<NUMType, DENType>& nb) const;
TRationalNumber<IntType> operator* (const TRationalNumber<IntType>& nb) const;
inline
TRationalNumber<NUMType, DENType> operator/ (const TRationalNumber<NUMType, DENType>& nb) const;
TRationalNumber<IntType> operator/ (const TRationalNumber<IntType>& nb) const;
inline
TRationalNumber<NUMType, DENType>& operator+= (const TRationalNumber<NUMType, DENType>& nb);
TRationalNumber<IntType>& operator+= (const TRationalNumber<IntType>& nb);
inline
TRationalNumber<NUMType, DENType>& operator-= (const TRationalNumber<NUMType, DENType>& nb);
TRationalNumber<IntType>& operator-= (const TRationalNumber<IntType>& nb);
inline
TRationalNumber<NUMType, DENType>& operator*= (const TRationalNumber<NUMType, DENType>& nb);
TRationalNumber<IntType>& operator*= (const TRationalNumber<IntType>& nb);
inline
TRationalNumber<NUMType, DENType>& operator/= (const TRationalNumber<NUMType, DENType>& nb);
TRationalNumber<IntType>& operator/= (const TRationalNumber<IntType>& nb);
/// Usual Boolean Opertor.
inline
bool operator== (const TRationalNumber<NUMType, DENType>& nb) const;
bool operator== (const TRationalNumber<IntType>& nb) const;
inline
bool operator!= (const TRationalNumber<NUMType, DENType>& nb) const;
bool operator!= (const TRationalNumber<IntType>& nb) const;
inline
bool operator< (const TRationalNumber<NUMType, DENType>& nb) const;
bool operator< (const TRationalNumber<IntType>& nb) const;
inline
bool operator<= (const TRationalNumber<NUMType, DENType>& nb) const;
bool operator<= (const TRationalNumber<IntType>& nb) const;
inline
bool operator> (const TRationalNumber<NUMType, DENType>& nb) const;
bool operator> (const TRationalNumber<IntType>& nb) const;
inline
bool operator>= (const TRationalNumber<NUMType, DENType>& nb) const;
bool operator>= (const TRationalNumber<IntType>& nb) const;
// @}
/// @name Cast function
/// @{
/// Implicit cast
// operator int () const;
//operator float () const;
inline
operator float () const;
operator double () const;
/// Explecit cast
inline
int to_int () const;
IntType to_integer () const;
inline
float to_float () const;
inline
......@@ -162,28 +164,28 @@ namespace vcsn
*
*/
inline void set_rational ();
inline void set_rational (const NUMType num, const DENType den);
inline void set_unsafe_rational (const NUMType num, const DENType den);
inline void set_rational (const IntType num, const IntType den);
inline void set_unsafe_rational (const IntType num, const IntType den);
/// @}
protected:
/// @name TRationalNumber<NUMType, DENType> attributs
/// @name TRationalNumber<IntType> attributs
/// @{
/// Fraction's numerator.
NUMType num_;
IntType num_;
/// Fraction's denominator.
DENType den_;
IntType den_;
//// @}
}; // TRationalNumber<NUMType, DENType>
}; // TRationalNumber<IntType>
template<typename NUMType, typename DENType>
template<typename IntType>
inline
std::ostream& operator<< (std::ostream&, const TRationalNumber<NUMType, DENType>&);
std::ostream& operator<< (std::ostream&, const TRationalNumber<IntType>&);
template<typename NUMType, typename DENType>
template<typename IntType>
inline
std::istream& operator>> (std::istream&, TRationalNumber<NUMType, DENType>&);
std::istream& operator>> (std::istream&, TRationalNumber<IntType>&);
typedef TRationalNumber<long long, unsigned long long> RationalNumber;
typedef TRationalNumber<long long> RationalNumber;
/// @}
} // !algebra
......
<
......@@ -21,299 +21,273 @@
# include <vaucanson/misc/algebra.hh>
# include <vaucanson/misc/contract.hh>
# include <iostream>
# include <cassert>
namespace vcsn {
namespace algebra {
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>::TRationalNumber ()
: num_ (NUMType(0)),
den_ (DENType(1))
TRationalNumber<IntType>::TRationalNumber ()
: num_ (IntType(0)), // 0 or 1
den_ (IntType(1))
{
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>::TRationalNumber (const NUMType num)
TRationalNumber<IntType>::TRationalNumber (const IntType num)
: num_ (num),
den_ (DENType(1))
den_ (IntType(1))
{
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>::TRationalNumber (const NUMType num, const DENType den)
TRationalNumber<IntType>::TRationalNumber (const IntType num, const IntType den)
{
set_rational (num, den);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>::TRationalNumber (const TRationalNumber<NUMType, DENType>& nb)
TRationalNumber<IntType>::TRationalNumber (const TRationalNumber<IntType>& nb)
{
set_rational (nb.num_, nb.den_);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>::~TRationalNumber ()
TRationalNumber<IntType>::~TRationalNumber ()
{}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
vcsn::algebra::TRationalNumber<NUMType, DENType>&
TRationalNumber<NUMType, DENType>::set (const NUMType num, const DENType den)
vcsn::algebra::TRationalNumber<IntType>&
TRationalNumber<IntType>::set (const IntType num, const IntType den)
{
set_rational (num, den);
return (*this);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
NUMType
TRationalNumber<NUMType, DENType>::num_get () const
IntType
TRationalNumber<IntType>::num_get () const
{
return num_;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
DENType
TRationalNumber<NUMType, DENType>::den_get () const
IntType
TRationalNumber<IntType>::den_get () const
{
return den_;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
std::ostream&
TRationalNumber<NUMType, DENType>::print (std::ostream& ostr) const
TRationalNumber<IntType>::print (std::ostream& ostr) const
{
if (den_ != 1)
return ostr << num_ << '/' << den_;
return ostr << num_;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>
TRationalNumber<NUMType, DENType>::operator+ (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>
TRationalNumber<IntType>::operator+ (const TRationalNumber<IntType>& nb) const
{
return TRationalNumber<NUMType, DENType> (num_ * nb.den_ + nb.num_ * den_, den_ * nb.den_);
TRationalNumber<IntType> r(*this);
r+=nb;
return r;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>
TRationalNumber<NUMType, DENType>::operator- (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>
TRationalNumber<IntType>::operator- (const TRationalNumber<IntType>& nb) const
{
using vcsn::misc::abs;
NUMType a = den_;
NUMType b = nb.den_;
return TRationalNumber<NUMType, DENType> ((num_ * b) - (nb.num_ * a), den_ * nb.den_);
TRationalNumber<IntType> r(*this);
r-=nb;
return r;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>
TRationalNumber<NUMType, DENType>::operator- () const
TRationalNumber<IntType>
TRationalNumber<IntType>::operator- () const
{
return TRationalNumber<NUMType, DENType> (- num_, den_);
return TRationalNumber<IntType> (- num_, den_);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>
TRationalNumber<NUMType, DENType>::operator* (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>
TRationalNumber<IntType>::operator* (const TRationalNumber<IntType>& nb) const
{
NUMType d1 = vcsn::misc::gcd (vcsn::misc::abs(num_), nb.den_get ());
NUMType d2 = vcsn::misc::gcd (den_, vcsn::misc::abs(nb.num_get ()));
return TRationalNumber<NUMType, DENType> ((num_ / d1) * (nb.num_get () / d2),
(den_ / d2) * (nb.den_get () / d1));
TRationalNumber<IntType> r(*this);
r*=nb;
return r;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>
TRationalNumber<NUMType, DENType>::operator/ (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>
TRationalNumber<IntType>::operator/ (const TRationalNumber<IntType>& nb) const
{
NUMType signe = 1;
assert(nb.num_ != 0);
NUMType numgcd = vcsn::misc::gcd (vcsn::misc::abs (num_), vcsn::misc::abs (nb.num_));
NUMType dengcd = vcsn::misc::gcd (den_, nb.den_);
if(nb.num_ < 0)
signe = -1;
return TRationalNumber<NUMType, DENType> (signe * ((num_ / numgcd)
* ((NUMType) nb.den_get() /dengcd)),
(signe * nb.num_get()
/ numgcd) *
(den_ / dengcd));
TRationalNumber<IntType> r(*this);
r/=nb;
return r;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>&
TRationalNumber<NUMType, DENType>::operator+= (const TRationalNumber<NUMType, DENType>& nb)
TRationalNumber<IntType>&
TRationalNumber<IntType>::operator+= (const TRationalNumber<IntType>& nb)
{
set_rational (num_ * nb.den_ + nb.num_ * den_, den_ * nb.den_);
IntType g = vcsn::misc::gcd(den_,nb.den_);
set_rational (nb.den_ / g * num_+ den_ / g * nb.num_, den_ / g * nb.den_);
return (*this);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>&
TRationalNumber<NUMType, DENType>::operator-= (const TRationalNumber<NUMType, DENType>& nb)
TRationalNumber<IntType>&
TRationalNumber<IntType>::operator-= (const TRationalNumber<IntType>& nb)
{
set_rational (num_ * nb.den_ - nb.num_ * den_, den_ * nb.den_);
IntType g = vcsn::misc::gcd(den_,nb.den_);
set_rational (nb.den_ / g * num_ - den_ / g * nb.num_, den_ / g * nb.den_);
return (*this);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>&
TRationalNumber<NUMType, DENType>::operator*= (const TRationalNumber<NUMType, DENType>& nb)
TRationalNumber<IntType>&
TRationalNumber<IntType>::operator*= (const TRationalNumber<IntType>& nb)
{
DENType d1 = vcsn::misc::gcd (vcsn::misc::abs(num_), nb.den_get ());
DENType d2 = vcsn::misc::gcd (den_, vcsn::misc::abs(nb.num_get ()));
set_unsafe_rational ((num_ / d1) * (nb.num_get () / d2),
(den_ / d2) * (nb.den_get () / d1));
IntType d1 = vcsn::misc::gcd (num_, nb.den_);
IntType d2 = vcsn::misc::gcd (den_, nb.num_);
set_unsafe_rational ((num_ / d1) * (nb.num_ / d2),
(den_ / d2) * (nb.den_ / d1));
return (*this);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>&
TRationalNumber<NUMType, DENType>::operator/= (const TRationalNumber<NUMType, DENType>& nb)
TRationalNumber<IntType>&
TRationalNumber<IntType>::operator/= (const TRationalNumber<IntType>& nb)
{
NUMType signe = 1;
assert(nb.num_ != 0);
NUMType numgcd = vcsn::misc::gcd (vcsn::misc::abs (num_), vcsn::misc::abs (nb.num_));
NUMType dengcd = vcsn::misc::gcd (den_, nb.den_);
if(nb.num_ < 0)
signe = -1;
set_unsafe_rational (signe * ((num_ / numgcd) * ((NUMType) nb.den_get() /dengcd)),
(signe * nb.num_get() / numgcd) * (den_ / dengcd));
IntType d1 = vcsn::misc::gcd (num_, nb.num_);// negative iff nb.num_ negative
IntType d2 = vcsn::misc::gcd (den_, nb.den_);
set_unsafe_rational ((num_ / d1) * (nb.den_ / d2),
(nb.num_ / d1) * (den_ / d2));
return *this;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
bool
TRationalNumber<NUMType, DENType>::operator== (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>::operator== (const TRationalNumber<IntType>& nb) const
{
//return (den_ * nb.num_ == nb.den_ * num_);
if (!num_)
return (!nb.num_);
return (!nb.num_);
return (den_ == nb.den_) && (num_ == nb.num_);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
bool
TRationalNumber<NUMType, DENType>::operator!= (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>::operator!= (const TRationalNumber<IntType>& nb) const
{
// return (den_ * nb.num_ != nb.den_ * num_);
if (!num_)
return (!!nb.num_);
return (den_ != nb.den_) || (num_ != nb.num_);
return !(*this == nb);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
bool
TRationalNumber<NUMType, DENType>::operator< (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>::operator< (const TRationalNumber<IntType>& nb) const
{
return num_ * nb.den_ < nb.num_ * den_;
return (num_ * nb.den_ < nb.num_ * den_);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
bool
TRationalNumber<NUMType, DENType>::operator<= (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>::operator<= (const TRationalNumber<IntType>& nb) const
{
return num_ * nb.den_ <= nb.num_ * den_;
return !(nb<*this);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
bool
TRationalNumber<NUMType, DENType>::operator> (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>::operator> (const TRationalNumber<IntType>& nb) const
{
return num_ * nb.den_ > nb.num_ * den_;
return nb<*this;;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
bool
TRationalNumber<NUMType, DENType>::operator>= (const TRationalNumber<NUMType, DENType>& nb) const
TRationalNumber<IntType>::operator>= (const TRationalNumber<IntType>& nb) const
{
return num_ * nb.den_ >= nb.num_ * den_;
return !(*this<nb);
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
TRationalNumber<NUMType, DENType>::operator float () const
TRationalNumber<IntType>::operator double () const
{
return to_float ();
return to_double ();
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
int
TRationalNumber<NUMType, DENType>::to_int () const
IntType
TRationalNumber<IntType>::to_integer () const
{
return num_ / den_;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
float
TRationalNumber<NUMType, DENType>::to_float () const
TRationalNumber<IntType>::to_float () const
{
return (static_cast<float> (num_)) / den_;
}
template<typename NUMType, typename DENType>
template<typename IntType>
inline
double
TRationalNumber<NUMType, DENType>::to_double () const
TRationalNumber<IntType>::to_double () const
{
return (static_cast<double> (num_)) / den_;
}
#include <iostream>
template<typename NUMType, typename DENType>
template<typename IntType>
inline
void
TRationalNumber<NUMType, DENType>::set_rational (const NUMType num, const DENType den)
TRationalNumber<IntType>::set_rational (const IntType num, const IntType den)
{
if (num)
{
assert(den);
NUMType div = vcsn::misc::gcd(vcsn::misc::abs(num), den);
IntType div = vcsn::misc::gcd(num, den); //negative iff den negative
num_ = num / div;