diff --git a/.gitattributes b/.gitattributes index 7ac2eb5b7f3..f383a54c6b1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/Polynomial/include/CGAL/Polynomial/Coercion_traits.h b/Polynomial/include/CGAL/Polynomial/Coercion_traits.h index c0a52d5b808..ec2cbe61d8c 100644 --- a/Polynomial/include/CGAL/Polynomial/Coercion_traits.h +++ b/Polynomial/include/CGAL/Polynomial/Coercion_traits.h @@ -7,18 +7,116 @@ // $Id:$ // // -// Author(s) : +// Author(s) : Michael Hemmer // // ============================================================================ -// 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 suggest that +// the coercion type of two polynomial types Polynomial and Polynomial +// is defined as Polynomial, where C is the coercion type. +// However, this is not in line with the fact that a Polynomial +// 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. + +#include + CGAL_BEGIN_NAMESPACE +namespace CGALi{ + +// A has less variables than B +template +class Coercion_traits_for_polynomial_comp_d + :public Coercion_traits_for_polynomial_comp_d< B, A , false >{}; + +// Polynomial has more variables than B +template +class Coercion_traits_for_polynomial_comp_d< Polynomial, B , false>{ + typedef Coercion_traits CT; +public: + typedef CGAL::Tag_true Are_explicit_interoperable; + typedef CGAL::Tag_false Are_implicit_interoperable; + + typedef Polynomial Type; + struct Cast{ + typedef Type result_type; + Type operator()(const Polynomial& 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 +class Coercion_traits_for_polynomial_equal_d + :public Coercion_traits_for_polynomial_comp_d {}; + +// number of variables is equal and at least one. +template +class Coercion_traits_for_polynomial_equal_d, Polynomial, d, d >{ + typedef Coercion_traits CT; +public: + typedef CGAL::Tag_true Are_explicit_interoperable; + typedef CGAL::Tag_false Are_implicit_interoperable; + typedef Polynomial Type; + struct Cast{ + typedef Type result_type; + Type operator()(const Polynomial& 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& 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 +class Coercion_traits_for_polynomial + : public Coercion_traits_for_polynomial_equal_d + < A , B , Dimension::value, Dimension::value >{}; + +}// namespace CGALi + +template +class Coercion_traits_for_level< Polynomial , Polynomial, CTL_POLYNOMIAL > + :public CGALi::Coercion_traits_for_polynomial< Polynomial, Polynomial > +{}; +template +class Coercion_traits_for_level< Polynomial , B , CTL_POLYNOMIAL > + :public CGALi::Coercion_traits_for_polynomial< Polynomial, B > +{}; +template +class Coercion_traits_for_level< A , Polynomial , CTL_POLYNOMIAL > + :public CGALi::Coercion_traits_for_polynomial< A , Polynomial > +{}; + + + + +#if 0 // COERCION_TRAITS BEGIN //Coercion_traits_polynomial----------------------------------- @@ -73,6 +171,8 @@ class Coercion_traits_for_level,CTL_POLYNOMIAL > :public Coercion_traits_for_level,B,CTL_POLYNOMIAL > {}; +#endif // 0 + // COERCION_TRAITS END CGAL_END_NAMESPACE diff --git a/Polynomial/test/Polynomial/Coercion_traits.cpp b/Polynomial/test/Polynomial/Coercion_traits.cpp new file mode 100644 index 00000000000..8b7490f601c --- /dev/null +++ b/Polynomial/test/Polynomial/Coercion_traits.cpp @@ -0,0 +1,166 @@ +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +template void test_coercion_from_to(A, B){ + CGAL::INTERN_COERCION_TRAITS::direct_coercion_from_to_test(); +}; + +template +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::Type POLY_INT_1; + typedef typename CGAL::Polynomial_type_generator::Type POLY_INT_2; + typedef typename CGAL::Polynomial_type_generator::Type POLY_INT_3; + typedef typename CGAL::Polynomial_type_generator::Type POLY_RAT_1; + typedef typename CGAL::Polynomial_type_generator::Type POLY_RAT_2; + typedef typename CGAL::Polynomial_type_generator::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 suggest that + // the coercion type of two polynomial types Polynomial and Polynomial + // is defined as Polynomial, where C is the coercion type. + // However, this is not in line with the fact that a Polynomial + // 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. 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 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 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 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 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 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 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 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(); +#endif +return 0; +};