changed behavior of Coercion_traits (see comments)

added test for Coercion_traits
This commit is contained in:
Michael Hemmer 2008-10-29 12:59:46 +00:00
parent 555ecfcf86
commit c0575b449e
3 changed files with 271 additions and 4 deletions

1
.gitattributes vendored
View File

@ -2986,6 +2986,7 @@ Polynomial/include/CGAL/Polynomial/square_free_factorize.h -text
Polynomial/include/CGAL/Polynomial/sturm_habicht_sequence.h -text
Polynomial/include/CGAL/Polynomial/subresultants.h -text
Polynomial/include/CGAL/Polynomial_type_generator.h -text
Polynomial/test/Polynomial/Coercion_traits.cpp -text
Polynomial/test/Polynomial/Polynomial_type_generator.cpp -text
Polynomial/test/Polynomial/polynomial_utils.cpp -text
Polynomial/test/Polynomial/sturm_habicht_sequence.cpp -text

View File

@ -7,18 +7,116 @@
// $Id:$
//
//
// Author(s) :
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
//
// ============================================================================
// TODO: The comments are all original EXACUS comments and aren't adapted. So
// they may be wrong now.
#ifndef CGAL_POLYNOMIAL_COERCION_TRAITS_H
#define CGAL_POLYNOMIAL_COERCION_TRAITS_H
// The coercion type of two polynomials is a polynomial in d=max(d1,d2)
// variables, where d1 and d2 are the number of variables the two
// polynomials. (This also includes the case of d1 = 0 or d2 = 0.)
// Moreover, the new Innermost_coefficient_type is the coercion type of the
// two Innermost_coefficient_types of the two involved polynomials.
// (Again, this is generalized if one of the involved types is just a scalar
// type)
// Though the coercion type is clear, the problem is how to match the
// variables. The recursive definition of Polynomial<Coeff> suggest that
// the coercion type of two polynomial types Polynomial<A> and Polynomial<B>
// is defined as Polynomial<C>, where C is the coercion type.
// However, this is not in line with the fact that a Polynomial<A>
// is interoperable with its coefficient type A, that is, if A is a polynomial
// the variables of A should not be moved outward while casting A to
// Polynomial<A>.
#include <CGAL/Polynomial/misc.h>
CGAL_BEGIN_NAMESPACE
namespace CGALi{
// A has less variables than B
template <typename A, typename B, bool less >
class Coercion_traits_for_polynomial_comp_d
:public Coercion_traits_for_polynomial_comp_d< B, A , false >{};
// Polynomial<A> has more variables than B
template <typename A, typename B >
class Coercion_traits_for_polynomial_comp_d< Polynomial<A>, B , false>{
typedef Coercion_traits<A,B> CT;
public:
typedef CGAL::Tag_true Are_explicit_interoperable;
typedef CGAL::Tag_false Are_implicit_interoperable;
typedef Polynomial<typename CT::Type> Type;
struct Cast{
typedef Type result_type;
Type operator()(const Polynomial<A>& poly) const {
typename CT::Cast cast;
return Type(::boost::make_transform_iterator(poly.begin(),cast),
::boost::make_transform_iterator(poly.end() ,cast));
}
Type operator()(const B& x) const {
typename CT::Cast cast;
return Type(cast(x));
}
};
};
// number of variables is different
template <typename A, typename B, int a, int b>
class Coercion_traits_for_polynomial_equal_d
:public Coercion_traits_for_polynomial_comp_d <A,B, a < b >{};
// number of variables is equal and at least one.
template <class A,class B, int d>
class Coercion_traits_for_polynomial_equal_d<Polynomial<A>, Polynomial<B>, d, d >{
typedef Coercion_traits<A,B> CT;
public:
typedef CGAL::Tag_true Are_explicit_interoperable;
typedef CGAL::Tag_false Are_implicit_interoperable;
typedef Polynomial<typename CT::Type> Type;
struct Cast{
typedef Type result_type;
Type operator()(const Polynomial<A>& poly) const {
typename CT::Cast cast;
return Type(::boost::make_transform_iterator(poly.begin(),cast),
::boost::make_transform_iterator(poly.end() ,cast));
}
Type operator()(const Polynomial<B>& poly) const {
typename CT::Cast cast;
return Type(::boost::make_transform_iterator(poly.begin(),cast),
::boost::make_transform_iterator(poly.end() ,cast));
}
};
};
// determine number of variables in each polynomial
template <typename A, typename B>
class Coercion_traits_for_polynomial
: public Coercion_traits_for_polynomial_equal_d
< A , B , Dimension<A>::value, Dimension<B>::value >{};
}// namespace CGALi
template <class A,class B>
class Coercion_traits_for_level< Polynomial<A> , Polynomial<B>, CTL_POLYNOMIAL >
:public CGALi::Coercion_traits_for_polynomial< Polynomial<A>, Polynomial<B> >
{};
template <class A,class B>
class Coercion_traits_for_level< Polynomial<A> , B , CTL_POLYNOMIAL >
:public CGALi::Coercion_traits_for_polynomial< Polynomial<A>, B >
{};
template <class A,class B>
class Coercion_traits_for_level< A , Polynomial<B> , CTL_POLYNOMIAL >
:public CGALi::Coercion_traits_for_polynomial< A , Polynomial<B> >
{};
#if 0
// COERCION_TRAITS BEGIN
//Coercion_traits_polynomial-----------------------------------
@ -73,6 +171,8 @@ class Coercion_traits_for_level<B,Polynomial<A>,CTL_POLYNOMIAL >
:public Coercion_traits_for_level<Polynomial<A>,B,CTL_POLYNOMIAL >
{};
#endif // 0
// COERCION_TRAITS END
CGAL_END_NAMESPACE

View File

@ -0,0 +1,166 @@
#include <CGAL/basic.h>
#include <cassert>
#include <CGAL/Polynomial_traits_d.h>
#include <CGAL/Arithmetic_kernel.h>
#include <CGAL/Polynomial.h>
#include <CGAL/Sqrt_extension.h>
#include <CGAL/Interval_nt.h>
#include <CGAL/Coercion_traits.h>
#include <CGAL/Polynomial_type_generator.h>
#include <CGAL/Test/_test_coercion_traits.h>
template<class A, class B> void test_coercion_from_to(A, B){
CGAL::INTERN_COERCION_TRAITS::direct_coercion_from_to_test<A,B>();
};
template <typename AK>
void test_coercion_traits(){
//CGAL::set_pretty_mode(std::cout);
typedef typename AK::Integer Integer;
typedef typename AK::Rational Rational;
typedef typename CGAL::Polynomial_type_generator<Integer, 1>::Type POLY_INT_1;
typedef typename CGAL::Polynomial_type_generator<Integer, 2>::Type POLY_INT_2;
typedef typename CGAL::Polynomial_type_generator<Integer, 3>::Type POLY_INT_3;
typedef typename CGAL::Polynomial_type_generator<Rational, 1>::Type POLY_RAT_1;
typedef typename CGAL::Polynomial_type_generator<Rational, 2>::Type POLY_RAT_2;
typedef typename CGAL::Polynomial_type_generator<Rational, 3>::Type POLY_RAT_3;
test_coercion_from_to(POLY_INT_1(), POLY_INT_1());
test_coercion_from_to(POLY_INT_1(), POLY_INT_2());
test_coercion_from_to(POLY_INT_1(), POLY_INT_3());
test_coercion_from_to(POLY_INT_2(), POLY_INT_2());
test_coercion_from_to(POLY_INT_2(), POLY_INT_3());
test_coercion_from_to(POLY_INT_3(), POLY_INT_3());
test_coercion_from_to(POLY_RAT_1(), POLY_RAT_1());
test_coercion_from_to(POLY_RAT_1(), POLY_RAT_2());
test_coercion_from_to(POLY_RAT_1(), POLY_RAT_3());
test_coercion_from_to(POLY_RAT_2(), POLY_RAT_2());
test_coercion_from_to(POLY_RAT_2(), POLY_RAT_3());
test_coercion_from_to(POLY_RAT_3(), POLY_RAT_3());
// Though the coercion type is clear, the problem is how to match the
// variables. The recursive definition of Polynomial<Coeff> suggest that
// the coercion type of two polynomial types Polynomial<A> and Polynomial<B>
// is defined as Polynomial<C>, where C is the coercion type.
// However, this is not in line with the fact that a Polynomial<A>
// is interoperable with its coefficient type A, that is, if A is a polynomial
// the variables of A should not be moved outward while casting A to
// Polynomial<A>. This is tested in the sequel.
{
POLY_INT_1 x_1 = CGAL::shift(POLY_INT_1(1),1,0);
POLY_INT_3 x_3 = CGAL::shift(POLY_INT_3(1),1,0);
POLY_INT_3 y_3 = CGAL::shift(POLY_INT_3(1),1,1);
POLY_INT_3 z_3 = CGAL::shift(POLY_INT_3(1),1,2);
typedef CGAL::Coercion_traits<POLY_INT_1,POLY_INT_3> CT;
assert(typename CT::Cast()(x_1) == x_3);
assert(typename CT::Cast()(x_1) != y_3);
assert(typename CT::Cast()(x_1) != z_3);
assert(typename CT::Cast()(x_3) == x_3);
assert(typename CT::Cast()(y_3) == y_3);
assert(typename CT::Cast()(z_3) == z_3);
}{
POLY_INT_1 x_1 = CGAL::shift(POLY_INT_1(1),1,0);
POLY_RAT_3 x_3 = CGAL::shift(POLY_RAT_3(1),1,0);
POLY_RAT_3 y_3 = CGAL::shift(POLY_RAT_3(1),1,1);
POLY_RAT_3 z_3 = CGAL::shift(POLY_RAT_3(1),1,2);
typedef CGAL::Coercion_traits<POLY_INT_1,POLY_RAT_3> CT;
assert(typename CT::Cast()(x_1) == x_3);
assert(typename CT::Cast()(x_1) != y_3);
assert(typename CT::Cast()(x_1) != z_3);
assert(typename CT::Cast()(x_3) == x_3);
assert(typename CT::Cast()(y_3) == y_3);
assert(typename CT::Cast()(z_3) == z_3);
}{
POLY_RAT_1 x_1 = CGAL::shift(POLY_RAT_1(1),1,0);
POLY_INT_3 x_3 = CGAL::shift(POLY_INT_3(1),1,0);
POLY_INT_3 y_3 = CGAL::shift(POLY_INT_3(1),1,1);
POLY_INT_3 z_3 = CGAL::shift(POLY_INT_3(1),1,2);
POLY_RAT_3 x_3r = CGAL::shift(POLY_RAT_3(1),1,0);
POLY_RAT_3 y_3r = CGAL::shift(POLY_RAT_3(1),1,1);
POLY_RAT_3 z_3r = CGAL::shift(POLY_RAT_3(1),1,2);
typedef CGAL::Coercion_traits<POLY_RAT_1,POLY_INT_3> CT;
assert(typename CT::Cast()(x_1) == x_3r);
assert(typename CT::Cast()(x_1) != y_3r);
assert(typename CT::Cast()(x_1) != z_3r);
assert(typename CT::Cast()(x_3) == x_3r);
assert(typename CT::Cast()(y_3) == y_3r);
assert(typename CT::Cast()(z_3) == z_3r);
}
{
POLY_INT_1 x_1 = CGAL::shift(POLY_INT_1(1),1,0);
POLY_INT_3 x_3 = CGAL::shift(POLY_INT_3(1),1,0);
POLY_INT_3 y_3 = CGAL::shift(POLY_INT_3(1),1,1);
POLY_INT_3 z_3 = CGAL::shift(POLY_INT_3(1),1,2);
typedef CGAL::Coercion_traits<POLY_INT_3,POLY_INT_1> CT;
assert(typename CT::Cast()(x_1) == x_3);
assert(typename CT::Cast()(x_1) != y_3);
assert(typename CT::Cast()(x_1) != z_3);
assert(typename CT::Cast()(x_3) == x_3);
assert(typename CT::Cast()(y_3) == y_3);
assert(typename CT::Cast()(z_3) == z_3);
}{
POLY_INT_1 x_1 = CGAL::shift(POLY_INT_1(1),1,0);
POLY_RAT_3 x_3 = CGAL::shift(POLY_RAT_3(1),1,0);
POLY_RAT_3 y_3 = CGAL::shift(POLY_RAT_3(1),1,1);
POLY_RAT_3 z_3 = CGAL::shift(POLY_RAT_3(1),1,2);
typedef CGAL::Coercion_traits<POLY_RAT_3,POLY_INT_1> CT;
assert(typename CT::Cast()(x_1) == x_3);
assert(typename CT::Cast()(x_1) != y_3);
assert(typename CT::Cast()(x_1) != z_3);
assert(typename CT::Cast()(x_3) == x_3);
assert(typename CT::Cast()(y_3) == y_3);
assert(typename CT::Cast()(z_3) == z_3);
}{
POLY_RAT_1 x_1 = CGAL::shift(POLY_RAT_1(1),1,0);
POLY_INT_3 x_3 = CGAL::shift(POLY_INT_3(1),1,0);
POLY_INT_3 y_3 = CGAL::shift(POLY_INT_3(1),1,1);
POLY_INT_3 z_3 = CGAL::shift(POLY_INT_3(1),1,2);
POLY_RAT_3 x_3r = CGAL::shift(POLY_RAT_3(1),1,0);
POLY_RAT_3 y_3r = CGAL::shift(POLY_RAT_3(1),1,1);
POLY_RAT_3 z_3r = CGAL::shift(POLY_RAT_3(1),1,2);
typedef CGAL::Coercion_traits<POLY_INT_3,POLY_RAT_1> CT;
assert(typename CT::Cast()(x_1) == x_3r);
assert(typename CT::Cast()(x_1) != y_3r);
assert(typename CT::Cast()(x_1) != z_3r);
assert(typename CT::Cast()(x_3) == x_3r);
assert(typename CT::Cast()(y_3) == y_3r);
assert(typename CT::Cast()(z_3) == z_3r);
}
/*
{
typedef CGAL::Coercion_traits<POLY_RAT_1,CGAL::Null_functor> CT;
BOOST_STATIC_ASSERT((
::boost::is_same< typename CT::Are_implicit_interoperable,
CGAL::Tag_false>::value));
}
*/
}
int main(){
#if CGAL_HAVE_DEFAULT_ARITHMETIC_KERNEL
typedef CGAL::Arithmetic_kernel AK;
test_coercion_traits<AK>();
#endif
return 0;
};