~ubuntu-branches/debian/stretch/cgal/stretch

« back to all changes in this revision

Viewing changes to include/CGAL/RS/signat_1.h

  • Committer: Package Import Robot
  • Author(s): Joachim Reichel
  • Date: 2014-04-05 10:56:43 UTC
  • mfrom: (1.2.4)
  • Revision ID: package-import@ubuntu.com-20140405105643-jgnrpu2thtx23zfs
Tags: 4.4-1
* New upstream release.
* Remove patches do-not-link-example-with-qt4-support-library.patch and
  fix_jet_fitting_3.patch (applied upstream).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2006-2013 INRIA Nancy-Grand Est (France). All rights reserved.
 
2
//
 
3
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
 
4
// modify it under the terms of the GNU Lesser General Public License as
 
5
// published by the Free Software Foundation; either version 3 of the License,
 
6
// or (at your option) any later version.
 
7
 
 
8
// See the file LICENSE.LGPL distributed with CGAL.
 
9
//
 
10
// Licensees holding a valid commercial license may use this file in
 
11
// accordance with the commercial license agreement provided with the software.
 
12
//
 
13
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
14
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
15
//
 
16
// $URL$
 
17
// $Id$
 
18
//
 
19
// Author: Luis Peñaranda <luis.penaranda@gmx.com>
 
20
 
 
21
#ifndef CGAL_RS_SIGNAT_1_H
 
22
#define CGAL_RS_SIGNAT_1_H
 
23
 
 
24
#include <CGAL/Gmpfi.h>
 
25
#include <CGAL/Polynomial_traits_d.h>
 
26
#include "exact_signat_1.h"
 
27
//#include <boost/mpl/assert.hpp>
 
28
#include <gmp.h>
 
29
 
 
30
namespace CGAL{
 
31
namespace RS_AK1{
 
32
 
 
33
template <class Polynomial_,class Bound_>
 
34
struct Signat_1{
 
35
        typedef Polynomial_                                     Polynomial;
 
36
        typedef Bound_                                          Bound;
 
37
        typedef CGAL::Polynomial_traits_d<Polynomial>           PT;
 
38
        typedef typename PT::Degree                             Degree;
 
39
        Polynomial pol;
 
40
        Signat_1(const Polynomial &p):pol(p){};
 
41
        CGAL::Sign operator()(const Bound&)const;
 
42
}; // struct Signat_1
 
43
 
 
44
template <class Polynomial_,class Bound_>
 
45
inline CGAL::Sign
 
46
Signat_1<Polynomial_,Bound_>::operator()(const Bound_ &x)const{
 
47
        typedef Bound_                                          Bound;
 
48
        typedef Real_embeddable_traits<Bound>                   REtraits;
 
49
        typedef typename REtraits::Sgn                          BSign;
 
50
        //typedef Algebraic_structure_traits<Bound>               AStraits;
 
51
        // This generic signat works only when Bound_ is an exact type. For
 
52
        // non-exact types, an implementation must be provided.
 
53
        //BOOST_MPL_ASSERT((boost::is_same<AStraits::Is_exact,Tag_true>));
 
54
        int d=Degree()(pol);
 
55
        Bound h(pol[d]);
 
56
        for(int i=1;i<=d;++i)
 
57
                h=h*x+pol[d-i];
 
58
        return BSign()(h);
 
59
}
 
60
 
 
61
template <>
 
62
inline CGAL::Sign
 
63
Signat_1<Polynomial<Gmpz>,Gmpfr>::operator()(const Gmpfr &x)const{
 
64
        // In 32-bit systems, using Gmpfr arithmetic to perform exact
 
65
        // evaluations can overflow. For that reason, we only use Gmpfr
 
66
        // arithmetic in 64-bit systems.
 
67
#if (GMP_LIMB_BITS==64)
 
68
        typedef ExactSignat_1<Polynomial,Gmpfr>                 Exact_sign;
 
69
#else
 
70
        typedef Signat_1<Polynomial,Gmpq>                       Exact_sign;
 
71
#endif
 
72
        // This seems to work faster for small polynomials:
 
73
        // return Exact_sign(pol)(x);
 
74
        int d=Degree()(pol);
 
75
        if(d==0)
 
76
                return pol[0].sign();
 
77
        Gmpfi h(pol[d],x.get_precision()+2*d);
 
78
        Uncertain<CGAL::Sign> indet=Uncertain<CGAL::Sign>::indeterminate();
 
79
        if(h.sign().is_same(indet))
 
80
                return Exact_sign(pol)(x);
 
81
        for(int i=1;i<=d;++i){
 
82
                h*=x;
 
83
                h+=pol[d-i];
 
84
                if(h.sign().is_same(indet))
 
85
                        return Exact_sign(pol)(x);
 
86
        }
 
87
        CGAL_assertion(!h.sign().is_same(indet));
 
88
        return h.sign();
 
89
}
 
90
 
 
91
// This is the same code as above.
 
92
template <>
 
93
inline CGAL::Sign
 
94
Signat_1<Polynomial<Gmpq>,Gmpfr>::operator()(const Gmpfr &x)const{
 
95
        typedef Signat_1<Polynomial,Gmpq>                       Exact_sign;
 
96
        int d=Degree()(pol);
 
97
        if(d==0)
 
98
                return pol[0].sign();
 
99
        Gmpfi h(pol[d],x.get_precision()+2*d);
 
100
        Uncertain<CGAL::Sign> indet=Uncertain<CGAL::Sign>::indeterminate();
 
101
        if(h.sign().is_same(indet))
 
102
                return Exact_sign(pol)(x);
 
103
        for(int i=1;i<=d;++i){
 
104
                h*=x;
 
105
                h+=pol[d-i];
 
106
                if(h.sign().is_same(indet))
 
107
                        return Exact_sign(pol)(x);
 
108
        }
 
109
        CGAL_assertion(!h.sign().is_same(indet));
 
110
        return h.sign();
 
111
}
 
112
 
 
113
} // namespace RS_AK1
 
114
} // namespace CGAL
 
115
 
 
116
#endif // CGAL_RS_SIGNAT_1_H