dust3d/thirdparty/cgal/CGAL-4.13/include/CGAL/RS/algebraic_z_1.h

363 lines
14 KiB
C
Raw Normal View History

// Copyright (c) 2006-2013 INRIA Nancy-Grand Est (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
// See the file LICENSE.LGPL distributed with CGAL.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author: Luis Peñaranda <luis.penaranda@gmx.com>
#ifndef CGAL_RS_ALGEBRAIC_Z_1_H
#define CGAL_RS_ALGEBRAIC_Z_1_H
#include "algebraic_1.h"
namespace CGAL{
namespace RS_AK1{
// This class represents an algebraic number storing two polynomials of
// which it is root: one of them is the given polynomial; the other one is
// an integer polynomial, which is used to perform the operations such as
// refinements. Since RS works only with integer polynomials, this
// architecture permits to convert the input polynomials only once.
template <class Polynomial_,
class ZPolynomial_,
class Bound_,
class ZRefiner_,
class ZComparator_,
class Ptraits_,
class ZPtraits_>
class Algebraic_z_1:
public Algebraic_1<Polynomial_,Bound_,ZRefiner_,ZComparator_,ZPtraits_>,
boost::totally_ordered<Algebraic_z_1<Polynomial_,
ZPolynomial_,
Bound_,
ZRefiner_,
ZComparator_,
Ptraits_,
ZPtraits_>,
double>{
protected:
typedef Polynomial_ Polynomial;
typedef ZPolynomial_ ZPolynomial;
typedef Bound_ Bound;
typedef ZRefiner_ ZRefiner;
typedef ZComparator_ ZComparator;
typedef ZPtraits_ ZPtraits;
typedef typename ZPtraits::Coefficient_type ZCoefficient;
typedef typename ZPtraits::Scale ZScale;
typedef Ptraits_ Ptraits;
typedef typename Ptraits::Coefficient_type Coefficient;
typedef typename Ptraits::Scale Scale;
typedef Algebraic_1<Polynomial,Bound,ZRefiner,ZComparator,ZPtraits>
Algebraic_base;
typedef Algebraic_z_1<Polynomial,
ZPolynomial,
Bound,
ZRefiner,
ZComparator,
Ptraits,
ZPtraits>
Algebraic;
ZPolynomial zpol;
public:
Algebraic_z_1(){};
Algebraic_z_1(const Polynomial &p,
const ZPolynomial &zp,
const Bound &l,
const Bound &r):Algebraic_base(p,l,r),zpol(zp){
CGAL_assertion(l<=r);
}
Algebraic_z_1(const Algebraic &a):
Algebraic_base(a.pol,a.left,a.right),zpol(a.zpol){}
Algebraic_z_1(const Bound &b){
typedef typename Ptraits::Shift Shift;
typedef typename ZPtraits::Shift ZShift;
this->left=b;
this->right=b;
Gmpq q(b);
this->pol=Coefficient(mpq_denref(q.mpq()))*
Shift()(Polynomial(1),1,0)-
Coefficient(mpq_numref(q.mpq()));
zpol=ZCoefficient(mpq_denref(q.mpq()))*
ZShift()(ZPolynomial(1),1,0)-
ZCoefficient(mpq_numref(q.mpq()));
CGAL_assertion(this->left==this->right);
CGAL_assertion(this->left==b);
}
template <class T>
Algebraic_z_1(const T &t){
typedef typename Ptraits::Shift Shift;
typedef typename ZPtraits::Shift ZShift;
CGAL::Gmpq q(t);
this->pol=Coefficient(mpq_denref(q.mpq()))*
Shift()(Polynomial(1),1,0)-
Coefficient(mpq_numref(q.mpq()));
zpol=ZCoefficient(mpq_denref(q.mpq()))*
ZShift()(ZPolynomial(1),1,0)-
ZCoefficient(mpq_numref(q.mpq()));
this->left=Bound(t,std::round_toward_neg_infinity);
this->right=Bound(t,std::round_toward_infinity);
CGAL_assertion(this->left<=t&&this->right>=t);
}
Algebraic_z_1(const CGAL::Gmpq &q){
typedef typename Ptraits::Shift Shift;
typedef typename ZPtraits::Shift ZShift;
this->pol=Coefficient(mpq_denref(q.mpq()))*
Shift()(Polynomial(1),1,0)-
Coefficient(mpq_numref(q.mpq()));
zpol=ZCoefficient(mpq_denref(q.mpq()))*
ZShift()(ZPolynomial(1),1,0)-
ZCoefficient(mpq_numref(q.mpq()));
this->left=Bound();
this->right=Bound();
mpfr_t b;
mpfr_init(b);
mpfr_set_q(b,q.mpq(),GMP_RNDD);
mpfr_swap(b,this->left.fr());
mpfr_set_q(b,q.mpq(),GMP_RNDU);
mpfr_swap(b,this->right.fr());
mpfr_clear(b);
CGAL_assertion(this->left<=q&&this->right>=q);
}
~Algebraic_z_1(){}
ZPolynomial get_zpol()const{return zpol;}
void set_zpol(const ZPolynomial &p){zpol=p;}
Algebraic operator-()const{
return Algebraic(Scale()(this->get_pol(),Coefficient(-1)),
ZScale()(get_zpol(),ZCoefficient(-1)),
-this->right,
-this->left);
}
#define CGAL_RS_COMPARE_ALGEBRAIC_Z(_a) \
(ZComparator()(get_zpol(),this->get_left(),this->get_right(), \
(_a).get_zpol(),(_a).get_left(),(_a).get_right()))
Comparison_result compare(Algebraic a)const{
return CGAL_RS_COMPARE_ALGEBRAIC_Z(a);
};
#define CGAL_RS_COMPARE_ALGEBRAIC_Z_TYPE(_t) \
bool operator<(_t t)const \
{Algebraic a(t);return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)==CGAL::SMALLER;} \
bool operator>(_t t)const \
{Algebraic a(t);return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)==CGAL::LARGER;} \
bool operator==(_t t)const \
{Algebraic a(t);return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)==CGAL::EQUAL;}
bool operator==(Algebraic a)const
{return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)==CGAL::EQUAL;}
bool operator!=(Algebraic a)const
{return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)!=CGAL::EQUAL;}
bool operator<(Algebraic a)const
{return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)==CGAL::SMALLER;}
bool operator<=(Algebraic a)const
{return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)!=CGAL::LARGER;}
bool operator>(Algebraic a)const
{return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)==CGAL::LARGER;}
bool operator>=(Algebraic a)const
{return CGAL_RS_COMPARE_ALGEBRAIC_Z(a)!=CGAL::SMALLER;}
CGAL_RS_COMPARE_ALGEBRAIC_Z_TYPE(double)
#undef CGAL_RS_COMPARE_ALGEBRAIC_Z_TYPE
#undef CGAL_RS_COMPARE_ALGEBRAIC_Z
#ifdef IEEE_DBL_MANT_DIG
#define CGAL_RS_DBL_PREC IEEE_DBL_MANT_DIG
#else
#define CGAL_RS_DBL_PREC 53
#endif
double to_double()const{
typedef Real_embeddable_traits<Bound> RT;
typedef typename RT::To_double TD;
ZRefiner()(get_zpol(),
this->get_left(),
this->get_right(),
CGAL_RS_DBL_PREC);
CGAL_assertion(TD()(this->get_left())==TD()(this->get_right()));
return TD()(this->get_left());
}
std::pair<double,double> to_interval()const{
typedef Real_embeddable_traits<Bound> RT;
typedef typename RT::To_interval TI;
return std::make_pair(TI()(this->get_left()).first,
TI()(this->get_right()).second);
}
#undef CGAL_RS_DBL_PREC
}; // class Algebraic_z_1
} // namespace RS_AK1
// We define Algebraic_z_1 as real-embeddable
template <class Polynomial_,
class ZPolynomial_,
class Bound_,
class ZRefiner_,
class ZComparator_,
class Ptraits_,
class ZPtraits_>
class Real_embeddable_traits<RS_AK1::Algebraic_z_1<Polynomial_,
ZPolynomial_,
Bound_,
ZRefiner_,
ZComparator_,
Ptraits_,
ZPtraits_> >:
public INTERN_RET::Real_embeddable_traits_base<
RS_AK1::Algebraic_z_1<Polynomial_,
ZPolynomial_,
Bound_,
ZRefiner_,
ZComparator_,
Ptraits_,
ZPtraits_>,
CGAL::Tag_true>{
typedef Polynomial_ P;
typedef ZPolynomial_ ZP;
typedef Bound_ B;
typedef ZRefiner_ R;
typedef ZComparator_ C;
typedef Ptraits_ T;
typedef ZPtraits_ ZT;
public:
typedef RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> Type;
typedef CGAL::Tag_true Is_real_embeddable;
typedef bool Boolean;
typedef CGAL::Sign Sign;
typedef CGAL::Comparison_result Comparison_result;
typedef INTERN_RET::Real_embeddable_traits_base<Type,CGAL::Tag_true>
Base;
typedef typename Base::Compare Compare;
class Sgn:public CGAL::cpp98::unary_function<Type,CGAL::Sign>{
public:
CGAL::Sign operator()(const Type &a)const{
return Compare()(a,Type(0));
}
};
class To_double:public CGAL::cpp98::unary_function<Type,double>{
public:
double operator()(const Type &a)const{return a.to_double();}
};
class To_interval:
public CGAL::cpp98::unary_function<Type,std::pair<double,double> >{
public:
std::pair<double,double> operator()(const Type &a)const{
return a.to_interval();
}
};
class Is_zero:public CGAL::cpp98::unary_function<Type,Boolean>{
public:
bool operator()(const Type &a)const{
return Sgn()(a)==CGAL::ZERO;
}
};
class Is_finite:public CGAL::cpp98::unary_function<Type,Boolean>{
public:
bool operator()(const Type&)const{return true;}
};
class Abs:public CGAL::cpp98::unary_function<Type,Type>{
public:
Type operator()(const Type &a)const{
return Sgn()(a)==CGAL::NEGATIVE?-a:a;
}
};
};
template <class P,class ZP,class B,class R,class C,class T,class ZT>
inline
RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> min
BOOST_PREVENT_MACRO_SUBSTITUTION(RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> a,
RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> b){
return(a<b?a:b);
}
template <class P,class ZP,class B,class R,class C,class T,class ZT>
inline
RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> max
BOOST_PREVENT_MACRO_SUBSTITUTION(RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> a,
RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> b){
return(a>b?a:b);
}
template <class P,class ZP,class B,class R,class C,class T,class ZT>
inline
std::ostream& operator<<(std::ostream &o,
const RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> &a){
return(o<<'['<<a.get_pol()<<','<<
a.get_zpol()<<','<<
a.get_left()<<','<<
a.get_right()<<']');
}
template <class P,class ZP,class B,class R,class C,class T,class ZT>
inline
std::istream& operator>>(std::istream &i,
RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT> &a){
std::istream::int_type c;
P pol;
ZP zpol;
B lb,rb;
c=i.get();
if(c!='['){
CGAL_error_msg("error reading istream, \'[\' expected");
return i;
}
i>>pol;
c=i.get();
if(c!=','){
CGAL_error_msg("error reading istream, \',\' expected");
return i;
}
i>>zpol;
c=i.get();
if(c!=','){
CGAL_error_msg("error reading istream, \',\' expected");
return i;
}
i>>lb;
c=i.get();
if(c!=','){
CGAL_error_msg("error reading istream, \',\' expected");
return i;
}
i>>rb;
c=i.get();
if(c!=']'){
CGAL_error_msg("error reading istream, \']\' expected");
return i;
}
a=RS_AK1::Algebraic_z_1<P,ZP,B,R,C,T,ZT>(pol,zpol,lb,rb);
return i;
}
} // namespace CGAL
#endif // CGAL_RS_ALGEBRAIC_Z_1_H