Developer documentation

solver_uv_bspline.hpp
Go to the documentation of this file.
1 /*******************************************************************
2  * This file is part of the source code of the realroot kernel.
3  * Author(s): J. Seland SINTEF
4  * B. Mourrain GALAAD, INRIA
5  ********************************************************************/
6 #ifndef realroot_solver_bspline_hpp
7 #define realroot_solver_bspline_hpp
8 /********************************************************************/
11 #include <realroot/solver.hpp>
12 //--------------------------------------------------------------------
13 #define NO_ROOT -1.0
14 #define TMPL template<class Real>
15 namespace mmx {
16 
17 struct Bspline{};
18 
19 //-----------------------------------------------------------------------------
20 TMPL
21 Real knotSum(Real* t, int k, int d)
22 {
23  Real ret = t[k+1];
24  for ( int i=2; i<=d; ++i) ret+=t[k+i];
25  return ret;
26 }
27 
28 //-----------------------------------------------------------------------------
29 TMPL
31  Real *m_t, *m_c;
32  unsigned m_n, maxn, m_k ;
33  int m_d;
34  Real eps;
35 
36  solver_bspline(unsigned n, unsigned d, unsigned N=100): m_n(n), maxn(N+n), m_d(d), eps(1e-7) {
37  m_t= new Real[2*n+N];
38  for(unsigned i=0; i< 2*n+N; i++) m_t[i]=Real(1);
39  m_c = new Real[n+N];
40  for(unsigned i=0; i< n+N; i++) m_c[i]=Real(0);
41  }
42 
43  int insert_knot ( const Real& x, int mu) ;
44  Real first_root ();
45 
46 };
47 
48 //-----------------------------------------------------------------------------
49 // insert knot x in interval mu by Boehms algorithm
50 // Note: t,c must have capacity at least n+1, n+d+2 respectively
51 // require that x>=t[mu]
52 TMPL
53 int solver_bspline<Real>::insert_knot( const Real& x, int mu)
54 {
55  mu = std::max(mu,m_d);
56  while ( x>=m_t[mu+1]) mu++;
57 
58  for ( int i=m_n; i>mu; i--) {
59  m_c[i] = m_c[i-1];
60  }
61 
62  for ( int i=mu; i>=mu-m_d+1; i--) {
63  const Real alpha = (x-m_t[i])/(m_t[i+m_d]-m_t[i]);
64  m_c[i] = (1.0-alpha) * m_c[i-1] + alpha * m_c[i];
65  }
66 
67  m_t[m_n+m_d] = 1.0;
68 
69  for ( int i=m_n; i>mu+1; --i)
70  m_t[i] = m_t[i-1];
71  m_t[mu+1] = x;
72 
73  // n++;
74  return mu;
75 }
76 
77 // --------------------------------------------------------------------------
78 TMPL
80 {
81 
82  unsigned k = 1;
83  Real x = NO_ROOT;
84 
85  for ( ; m_n < maxn; ++m_n ) {
86 
87  while( k<m_n && (m_c[k-1]*m_c[k] > 0.0) )
88  ++k;
89 
90 
91  // Off end?
92  if ( k >= m_n ) {
93  //if (x!= NO_ROOT)
94  //x = -x; // NO_ROOT;
95  x = NO_ROOT;
96  break;
97  }
98 
99  // Interval converged?
100  const Real diff = m_t[k+m_d]-m_t[k];
101 
102  if (diff<eps) {
103  x = m_t[k];
104  break;
105  }
106 
107  const Real av = knotSum(m_t,k-1, m_d);
108  const Real lambda = m_c[k-1]/(m_c[k-1]-m_c[k]);
109  x = (av + lambda*diff)/Real(m_d);
110 
111  // Stopping criterion
112  const Real e = std::max(x, m_t[k+m_d-1]) - std::min(x, m_t[k+1] );
113  // const Real e = max(fabs(x-t[k+1]),fabs(x-t[k+m_d-1]));
114  if (e < eps)
115  break;
116 
117  // Refine spline
118  insert_knot(x,k);
119  }
120 
121  // dx = d*(m_c[k]-m_c[k-1])/(t[k+m_d]-t[k]);
122  m_k = k;
123  return x;
124 }
125 //--------------------------------------------------------------------
126 template<class Ring>
127 struct solver<Ring, Bspline> {
128  typedef double solution_t;
130 
131  template<class POL,class T> static solution_t
132  first_root(const POL& p, const T& u, const T& v);
133 
134  template<class POL> static solution_t
135  first_root(const POL& p);
136 
137 };
138 //--------------------------------------------------------------------
142 template<class Ring>
143 template<class POL, class T>
146  const T& u, const T& v) {
147 
148  typedef typename Ring::scalar_t Real;
149  //typedef typename POL::Ring ring_t;
150  //typedef typename solver<Ring, Bspline>::base_t base_t;
151  typedef GMP::rational rational;
152 
153  rational U,V;
154  let::assign(U,u);
155  let::assign(V,v);
156  int sz= degree(p)+1;
157 
158  std::vector<rational> bp(sz);
159  univariate::convertm2b(bp,p,sz,U,V);
160 
161  solver_bspline<Real> slv(sz,sz-1);
162 
163  for ( int i = 0; i < sz; i ++ ) {
164  slv.m_c[i]=as<Real>(bp[i]);
165  slv.m_t[i]=Real(0);
166  }
167 
168  return u +(v-u)*slv.first_root();
169 
170 }
171 
174 template<class Ring>
175 template<class POL>
178 
179  typedef typename Ring::Scalar Real;
180  //typedef typename POL::Ring ring_t;
181  //typedef typename solver<Ring, Bspline>::base_t base_t;
182  typedef GMP::integer integer;
183  typedef GMP::rational rational;
184 
185 
186  int d= degree(p), sz=d+1;
187  solver_bspline<Real> slv(sz,sz-1);
188 
189  std::vector<rational> bp(sz);
191  rational c;
192  if(p[0]==0)
193  return 0;
194  else if(p[0]<0) {
195  numerics::rounding<Real> rnd( numerics::rnd_up() );
196  for(int i=0;i<sz;i++) {
197  c= as<rational>(p[i])/bn(d,i);
198  slv.m_c[i]=as<Real>(c);
199  }
200  } else {
201  numerics::rounding<Real> rnd( numerics::rnd_dw() );
202  for(int i=0;i<sz;i++) {
203  c= as<rational>(p[i])/bn(d,i);
204  slv.m_c[i]=as<Real>(c);
205  }
206  }
207  for ( int i = 0; i < sz; i ++ ) {
208  slv.m_t[i]=Real(0);
209  }
210 
211  Real x= slv.first_root();
212 
213  return x/(1-x);
214 
215 }
216 //====================================================================
217 } //namespace mmx
218 #undef TMPL
219 #undef NO_ROOT
220 #endif //realroot_solver_bspline_hpp
221 
Real * m_t
Definition: solver_uv_bspline.hpp:31
TMPL Polynomial diff(const Polynomial &pol, int v)
Multivariate Polynomial Differentiation.
Definition: polynomial_fcts.hpp:99
dynamic_exp< E >::degree_t degree(const dynamic_exp< E > &t)
Definition: dynamicexp.hpp:191
unsigned maxn
Definition: solver_uv_bspline.hpp:32
solver_bspline(unsigned n, unsigned d, unsigned N=100)
Definition: solver_uv_bspline.hpp:36
Real eps
Definition: solver_uv_bspline.hpp:34
Definition: solver_uv_bspline.hpp:30
TMPL int N(const MONOMIAL &v)
Definition: monomial_glue.hpp:60
unsigned m_k
Definition: solver_uv_bspline.hpp:32
unsigned m_n
Definition: solver_uv_bspline.hpp:32
TMPL Real knotSum(Real *t, int k, int d)
Definition: solver_uv_bspline.hpp:21
Definition: rounding_mode.hpp:71
double solution_t
Definition: solver_uv_bspline.hpp:128
Real first_root()
Definition: solver_uv_bspline.hpp:79
Real * m_c
Definition: solver_uv_bspline.hpp:31
int m_d
Definition: solver_uv_bspline.hpp:33
#define min(a, b)
Definition: parser_def.c:475
Definition: solver.hpp:68
#define NO_ROOT
Definition: solver_uv_bspline.hpp:13
TMPL POL
Definition: polynomial_dual.hpp:74
Definition: binomials.hpp:68
#define Scalar
Definition: polynomial_operators.hpp:12
const C & c
Definition: Interval_glue.hpp:45
Definition: solver_uv_bspline.hpp:17
#define TMPL
Definition: solver_uv_bspline.hpp:14
void convertm2b(T &bz, const P &p, unsigned size, const C &a, const C &b)
Definition: univariate.hpp:847
solver_bspline< typename Ring::Scalar > base_t
Definition: solver_uv_bspline.hpp:129
void assign(A &a, const B &b)
Generic definition of the assignement function.
Definition: assign.hpp:97
int insert_knot(const Real &x, int mu)
Definition: solver_uv_bspline.hpp:53
Interval< T, r > max(const Interval< T, r > &a, const Interval< T, r > &b)
Definition: Interval_fcts.hpp:135
Definition: array.hpp:12
Definition: scalar.hpp:24
Home