48#ifndef VIGRA_RATIONAL_HPP
49#define VIGRA_RATIONAL_HPP
55#include "mathutil.hxx"
56#include "numerictraits.hxx"
57#include "metaprogramming.hxx"
80template <
typename IntType>
121template <
typename IntType>
127 if (n == zero ||
m == zero)
140class bad_rational :
public std::domain_error
143 explicit bad_rational() : std::domain_error(
"bad rational: zero denominator") {}
146template <
typename IntType>
149template <
typename IntType>
150Rational<IntType> abs(
const Rational<IntType>& r);
151template <
typename IntType>
152Rational<IntType> pow(
const Rational<IntType>& r,
int n);
153template <
typename IntType>
154Rational<IntType>
floor(
const Rational<IntType>& r);
155template <
typename IntType>
156Rational<IntType>
ceil(
const Rational<IntType>& r);
192template <
typename IntType>
252 den(
IntType(1.0/epsilon + 0.5))
346 return den == zero && num > zero;
354 return den == zero && num < zero;
362 return den == zero && num != zero;
372 return num == zero ? 0 : num < zero ? -1 : 1;
389template <
typename IntType>
390inline Rational<IntType>&
401template <
typename IntType>
409 if(r.den == zero &&
sign()*r.
sign() < 0)
410 throw bad_rational();
415 assign(r.num, zero,
false);
451template <
typename IntType>
459 if(r.den == zero &&
sign()*r.
sign() > 0)
460 throw bad_rational();
465 assign(-r.num, zero,
false);
485template <
typename IntType>
494 throw bad_rational();
501 throw bad_rational();
502 num = r.num *
sign();
519template <
typename IntType>
528 throw bad_rational();
536 throw bad_rational();
563template <
typename IntType>
571template <
typename IntType>
579template <
typename IntType>
590 throw bad_rational();
606template <
typename IntType>
617 throw bad_rational();
638template <
typename IntType>
646template <
typename IntType>
655template <
typename IntType>
664 throw bad_rational();
738#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
741struct NumericTraits<Rational<T> >
743 typedef Rational<T> Type;
744 typedef Rational<typename NumericTraits<T>::Promote> Promote;
745 typedef Rational<typename NumericTraits<T>::RealPromote> RealPromote;
746 typedef std::complex<Rational<RealPromote> > ComplexPromote;
749 typedef typename NumericTraits<T>::isIntegral isIntegral;
750 typedef VigraTrueType isScalar;
751 typedef typename NumericTraits<T>::isSigned isSigned;
752 typedef VigraTrueType isOrdered;
753 typedef VigraFalseType isComplex;
755 static Type zero() {
return Type(0); }
756 static Type one() {
return Type(1); }
757 static Type nonZero() {
return one(); }
759 static Promote toPromote(Type
const & v)
760 {
return Promote(v.numerator(), v.denominator(),
false); }
761 static RealPromote toRealPromote(Type
const & v)
762 {
return RealPromote(v.numerator(), v.denominator(),
false); }
763 static Type fromPromote(Promote
const & v)
764 {
return Type(NumericTraits<T>::fromPromote(v.numerator()),
765 NumericTraits<T>::fromPromote(v.denominator()),
false); }
766 static Type fromRealPromote(RealPromote
const & v)
767 {
return Type(NumericTraits<T>::fromRealPromote(v.numerator()),
768 NumericTraits<T>::fromRealPromote(v.denominator()),
false); }
772struct NormTraits<Rational<T> >
774 typedef Rational<T> Type;
775 typedef typename NumericTraits<Type>::Promote SquaredNormType;
776 typedef Type NormType;
780struct PromoteTraits<Rational<T>, Rational<T> >
782 typedef Rational<typename PromoteTraits<T, T>::Promote> Promote;
783 static Promote toPromote(Rational<T>
const & v) {
return v; }
786template <
class T1,
class T2>
787struct PromoteTraits<Rational<T1>, Rational<T2> >
789 typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
790 static Promote toPromote(Rational<T1>
const & v) {
return v; }
791 static Promote toPromote(Rational<T2>
const & v) {
return v; }
794template <
class T1,
class T2>
795struct PromoteTraits<Rational<T1>, T2 >
797 typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
798 static Promote toPromote(Rational<T1>
const & v) {
return v; }
799 static Promote toPromote(T2
const & v) {
return Promote(v); }
802template <
class T1,
class T2>
803struct PromoteTraits<T1, Rational<T2> >
805 typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
806 static Promote toPromote(T1
const & v) {
return Promote(v); }
807 static Promote toPromote(Rational<T2>
const & v) {
return v; }
837template <
typename IntType>
844template <
typename IntType>
851template <
typename IntType>
858template <
typename IntType>
865template <
typename IntType>
872template <
typename IntType>
879template <
typename IntType>
880inline Rational<IntType>
887template <
typename IntType>
888inline Rational<IntType>
895template <
typename IntType>
896inline Rational<IntType>
903template <
typename IntType>
904inline Rational<IntType>
911template <
typename IntType>
912inline Rational<IntType>
919template <
typename IntType>
920inline Rational<IntType>
927template <
typename IntType>
928inline Rational<IntType>
935template <
typename IntType>
936inline Rational<IntType>
953template <
typename IntType1,
typename IntType2>
957 return l.denominator() == r.denominator() &&
958 l.numerator() == r.numerator();
963template <
typename IntType1,
typename IntType2>
967 return ((
l.denominator() ==
IntType1(1)) && (
l.numerator() ==
i));
971template <
typename IntType1,
typename IntType2>
979template <
typename IntType1,
typename IntType2>
983 return l.denominator() != r.denominator() ||
984 l.numerator() != r.numerator();
989template <
typename IntType1,
typename IntType2>
993 return ((
l.denominator() !=
IntType1(1)) || (
l.numerator() !=
i));
997template <
typename IntType1,
typename IntType2>
1005template <
typename IntType1,
typename IntType2>
1010 typedef typename PromoteTraits<IntType1, IntType2>::Promote
IntType;
1015 if(
l.denominator() == zero)
1017 if(r.denominator() == zero)
1019 return l.numerator() < r.numerator();
1023 return l.numerator() < zero;
1025 if(r.denominator() == zero)
1028 return r.numerator() > zero;
1030 if(
l.numerator() >= zero && r.numerator() <= zero)
1033 if(
l.numerator() <= zero && r.numerator() >= zero)
1040 return (
l.numerator()/
gcd1) * (r.denominator()/
gcd2) <
1041 (
l.denominator()/
gcd2) * (r.numerator()/
gcd1);
1045template <
typename IntType1,
typename IntType2>
1050 typedef typename PromoteTraits<IntType1, IntType2>::Promote
IntType;
1055 if(
l.denominator() == zero)
1058 return l.numerator() < zero;
1060 if(
l.numerator() >= zero &&
i <= zero)
1063 if(
l.numerator() <= zero &&
i >= zero)
1070 if (
l.numerator() > zero)
1071 return (
l.numerator()/
l.denominator()) <
i;
1073 return -
i < (-
l.numerator()/
l.denominator());
1077template <
typename IntType1,
typename IntType2>
1085template <
typename IntType1,
typename IntType2>
1093template <
typename IntType1,
typename IntType2>
1098 if (
l.numerator() ==
i &&
l.denominator() ==
IntType1(1))
1106template <
typename IntType1,
typename IntType2>
1114template <
typename IntType1,
typename IntType2>
1122template <
typename IntType1,
typename IntType2>
1130template <
typename IntType1,
typename IntType2>
1138template <
typename IntType1,
typename IntType2>
1146template <
typename IntType1,
typename IntType2>
1154template <
typename IntType1,
typename IntType2>
1168template <
typename IntType>
1169inline Rational<IntType>
1172 if (r.numerator() >=
IntType(0))
1179template <
typename IntType>
1180inline Rational<IntType>
1187template <
typename IntType>
1188inline typename NormTraits<Rational<IntType> >::SquaredNormType
1198template <
typename IntType>
1206 if(r.denominator() == zero)
1207 throw bad_rational();
1212 if(r.numerator() == zero)
1214 if(r.denominator() == zero)
1220 if(r.denominator() == zero || r.numerator() == zero)
1247template <
typename IntType>
1252 if(r.denominator() == zero || r.denominator() == one)
1254 return r.numerator() < zero ?
1260template <
typename IntType>
1265 if(r.denominator() == zero || r.denominator() == one)
1267 return r.numerator() <
IntType(0) ?
1288template <
typename T,
typename IntType>
1291 return static_cast<T
>(
src.numerator())/
src.denominator();
1302template <
typename IntType>
1305 os << r.numerator() <<
'/' << r.denominator();
Class for a single RGB value.
Definition rgbvalue.hxx:128
RGBValue()
Definition rgbvalue.hxx:209
Definition rational.hxx:194
Rational(param_type n, param_type d, bool doNormalize=true)
Definition rational.hxx:236
Rational(param_type n)
Definition rational.hxx:223
param_type numerator() const
Definition rational.hxx:269
Rational & operator=(param_type n)
Definition rational.hxx:261
Rational(double v, double epsilon=1e-4)
Definition rational.hxx:248
bool is_ninf() const
Definition rational.hxx:351
bool operator!() const
Definition rational.hxx:339
Rational & operator/=(const Rational &r)
Definition rational.hxx:520
param_type denominator() const
Definition rational.hxx:273
bool is_pinf() const
Definition rational.hxx:343
Rational operator++(int)
Definition rational.hxx:332
Rational & operator--()
Definition rational.hxx:647
bool is_inf() const
Definition rational.hxx:359
IntType value_type
Definition rational.hxx:198
Rational & operator+=(const Rational &r)
Definition rational.hxx:402
Rational & operator*=(const Rational &r)
Definition rational.hxx:486
Rational operator--(int)
Definition rational.hxx:335
Rational(Rational< U > const &r)
Definition rational.hxx:216
Rational()
Definition rational.hxx:208
If< typenameTypeTraits< IntType >::isBuiltinType, IntType, IntTypeconst & >::type param_type
Definition rational.hxx:204
Rational & operator++()
Definition rational.hxx:639
Rational & assign(param_type n, param_type d, bool doNormalize=true)
Definition rational.hxx:391
Rational & operator-=(const Rational &r)
Definition rational.hxx:452
int sign() const
Definition rational.hxx:369
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition fixedpoint.hxx:667
Diff2D operator+(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:725
bool operator<=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less or equal
Definition fixedpoint.hxx:521
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition fftw3.hxx:1037
bool operator>=(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater or equal
Definition fixedpoint.hxx:539
IntType lcm(IntType n, IntType m)
Definition rational.hxx:122
IntType gcd(IntType n, IntType m)
Definition rational.hxx:81
T sign(T t)
The sign function.
Definition mathutil.hxx:591
bool operator>(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
greater
Definition fixedpoint.hxx:530
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude)
Definition fftw3.hxx:1044
bool operator<(FixedPoint< IntBits1, FracBits1 > l, FixedPoint< IntBits2, FracBits2 > r)
less than
Definition fixedpoint.hxx:512
T rational_cast(const Rational< IntType > &src)
Definition rational.hxx:1289
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition fftw3.hxx:825
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition fixedpoint.hxx:675
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition fftw3.hxx:841
Diff2D operator-(Diff2D const &a, Diff2D const &b)
Definition diff2d.hxx:697