Developer documentation

solver_mv_monomial_tests.hpp
Go to the documentation of this file.
1 /********************************************************************
2  * Author(s): A. Mantzaflaris, GALAAD, INRIA
3  ********************************************************************/
4 
5 # pragma once
6 /********************************************************************/
7 
9 # include <realroot/ring.hpp>
12 
13 # include <realroot/polynomial.hpp>
14 # include <realroot/homography.hpp>
16 # include <realroot/Interval.hpp>
17 //# include <linalg/matrix.hpp>
18 # include <stack>
19 
20 # include <realroot/solver_ucf.hpp>
22 
23 
24 # define TMPL template<class POL>
25 # define DPOL polynomial<double,with<MonomialTensor> >
26 # define BOX box_rep<POL>
27 
28 # define INFO 1
29 # define TODOUBLE as<double>
30 
31 //====================================================================
32 namespace mmx {
33 //====================================================================
34 namespace realroot {
35 
36  template<class POL, class FT> int topological_degree_2d(BOX* b);
37 
39  TMPL
40  inline bool no_variation(POL & p)
41  {
42  return !has_sign_variation(p.begin(),p.end()) ;
43  };
44 
45 
46 //Jacobian
47 
48  TMPL
49  inline DPOL * jacobian(Seq<POL*>& S0)
50  {
51  int n=S0.size();
52  DPOL * jac;//[n*n];
53  POL df;
54  jac= new DPOL [n*n];
55 
56  for( int i=0;i<n;i++)
57  {
58  for( int k=0;k<n;k++)
59  {
60  df= diff( *(S0[i]),k);
61  let::assign( jac[i*n+k] , df);
62  }
63 
64  }
65  return jac;
66  }
67 
68 
69  template<class T> inline
70  void precondition (Seq<T> val, DPOL * mat, int n)
71  {
72  int m(val.size());
73  T *ev;//[m*n];
74  ev= new T [m*n];
75 
76  for( int i=0;i<m;i++)
77  {
78  for( int k=0;k<n;k++)
79  {
80  tensor::eval( ev[i*m+k] , mat[i*m+k].rep(),
81  val , m );
82  }
83  }
84  return ev;
85  }
86 
87 
88 
89 
90  template<class T> inline
91  T * eval_poly_matrix(Seq<T> val, DPOL * mat, int n)
92  {
93  int m(val.size());
94  T *ev;//[m*n];
95  ev= new T [m*n];
96 
97  for( int i=0;i<m;i++)
98  {
99  for( int k=0;k<n;k++)
100  {
101  tensor::eval( ev[i*m+k] , mat[i*m+k].rep(),
102  val , m );
103  }
104  }
105  return ev;
106  }
107 
108  template<class T> inline
109  int signof_det(T *mat,const int& n)
110  { // mat= double[n*n]
111  double ev;
112  ev= det(mat,n);
113 
114  if (ev< .1e-15) return (0);
115  return (ev>0?1:-1);
116  }
117 
118  template<class T>
119  T* submatrix(T *matrix, int order, int i, int j)
120  {
121  int n=order-1;
122  T * subm;//[n*n];
123  int p, q; // Indexes for matrix
124  int a = 0, b; // Indexes for subm
125  subm = new T [n*n];
126 
127  for(p = 0; p < order; p++) {
128  if(p==i) continue; //Skip ith row
129 
130  b = 0;
131 
132  for(q = 0; q < order; q++) {
133  if(q==j) continue; //Skip jth column
134  subm[a*order + b++] = matrix[p*order+q];
135  }
136  a++; //Increment row index
137  }
138  return subm;
139  }
140 
141  // Compute matrix determinant, recursively
142  template<class T>
143  T det(T *mat, int order)
144  {
145  if(order == 1)
146  return mat[0]; // Matrix is of order one
147  int i;
148  T ev(0);
149 
150  for(i = 0; i < order; i++)
151  {
152  //std::cout<<"entering"<<order<<",i="<<i <<std::endl;
153  ev += T(i%2==0?1:-1)* mat[i*order] * det(submatrix(mat, order, i, 0), order - 1);
154 
155  //std::cout<<"OK, ("<<order<<" "<<i<<")"<<std::endl;
156  }
157  return ev;
158  }
159 
160 
161 //
162  template<class FT>
163  inline int signof(DPOL * p, Seq<FT> t)
164  {
165 
166  Interval<double> ev;
167  //int dim= p->nbvar();
168 
169  tensor::eval( ev , p->rep() ,
170  t , t.size() );
171 
172  if (ev< .1e-10) return (0);
173  return (ev>0?1:-1);
174  }
175 
176 
177  /*
178  template<class C>
179  inline bool is_root(Seq<C> t)
180  {
181  assert( t.size()==dim );
182  C ev;
183  for ( unsigned i=0; i!=S.size() ; ++i )
184  {
185  tensor::eval( ev , S[i].rep() , t , dim );
186  if ( ev != 0 )
187  return false;
188  }
189  return true;
190  }
191  */
192 
193  TMPL
194  bool inline miranda_test(Seq<POL>& S,const int i,const int j)
195  {
196  POL u,l;
197 
198  tensor::face(l, S[i], j, 0);
199  tensor::face(u, S[i], j, 1);
200  //std::cout<<"l="<<l<<",u="<<u<<std::endl;
201 
202  return ( no_variation(l) &&
203  no_variation(u) &&
204  (l[0]>0)!=(u[0]>0) );
205  };
206 
208  // assumes a square system for now
209  template<class POL>
210  bool include1(BOX* b, DPOL * J)
211  {
212  Interval<double> ev(0);
213  Interval<double> * m;
214  unsigned i,j,c; //,r ;
215  POL u,l;
216  Seq<POL> SS= b->system();
217  unsigned dim= b->nbvar();
218 
219  bool t[dim][dim];
220 
221  m= eval_poly_matrix( b->template domain<double>() ,J,dim);
222 
223 // std::cout<<"Ok " <<std::endl;
224 // double dm[9];
225 // for(i = 0; i < 9; i++)
226 // { dm[i]= m[i].M;
227 // std::cout<<"dm["<<i<<"]="<<dm[i] <<std::endl;
228 // }
229 // ev= det(dm,dim);
230 // std::cout<<"Ok ="<<ev <<std::endl;
231 
232 // for(i = 0; i < 9; i++)
233 // std::cout<<"m["<<i<<"]="<<m[i] <<std::endl;
234 
235  // std::cout<<"SUB "<<std::endl;
236  // ev= det(submatrix(m, 3, 2, 0), 2);
237  // std::cout<<"FULL "<<std::endl;
238 
239  ev=det(m,dim);
240 
241  if ( ev.m*ev.M < 0 )
242  return false;
243 
244  for (i=0; i!=dim;++i)
245  for (j=0; j!=dim;++j){
246  t[i][j]= miranda_test(SS,i,j);
247  //std::cout<<"mir("<<i<<","<<j<<")="<< t[i][j] <<std::endl;
248  }
249 
250  c=0;
251  for (i=0; i!=dim;++i)
252  for (j=0; j!=dim;++j)
253  if (t[i][j]==true)
254  {
255  c++; break;
256  }
257  if (c<dim) return false;
258 
259  c=0;
260  for (i=0; i!=dim;++i)
261  for (j=0; j!=dim;++j)
262  if (t[j][i]==true)
263  {
264  c++; break;
265  }
266  if (c<dim) return false;
267 
268  //std::cout<<"INCLUDE. ev="<<ev<<", c="<<c <<"*dim:"<<dim <<std::endl;
269  return true;
270  };
271 
273  TMPL
274  bool include2(BOX* b,DPOL * J)
275  {
276  Interval<double> ev;
277  Interval<double> * m;
278 
279  //Seq<POL> SS= b->system();
280  unsigned dim= b->nbvar();
281 
282  // Check Jacobian's sign
283  m= eval_poly_matrix( b->template domain<double>() ,J,dim);
284  ev= det(m,dim);
285  if ( ev.m*ev.M < 0 )
286  return false;
287 
288  int td= topological_degree_2d<POL, double>(b);
289 
290  //if ( (td==-1 || td==1) )
291  //{ std::cout<<"INCLUDE. ev="<<ev<<", td="<<td <<std::endl;
292  //this->print(); }
293 
294  return ( (td==-1 || td==1) );
295  }
296 
298  template<class POL>
299  bool include3(BOX* b,DPOL * J, Seq<POL*>& S0)
300  {
301  double *fc, *jc, *ijc;
302  Interval<double> ev, *jb, *m;
303  Seq<double> c= b->point( b->middle() ) ;
305  unsigned i,j,n= b->nbvar();
306  DPOL tmp;
307 
308  fc= new double[n]; // system S0 evaluated on c
309  for(i=0; i< n;i++ )
310  {
311  let::assign(tmp, *S0[i]) ;
312  tensor::eval( fc[i] , tmp.rep(), c , n );
313  }
314  bx= b->template domain<double>(); // box
315  jc= eval_poly_matrix( c, J, n); // Jacobian evaluated on c
316  ijc= new double[n*n];
317  linear::LUinverse(ijc, jc, n); // Inverse of above
318  jb= eval_poly_matrix( bx, J, n); // Jacobian evaluated on box
319 
320  m= new Interval<double>[n*n];
321  for(i=0; i< n;i++ )
322  for(j=0; j< n;j++ )
323  m[i*n+j] += ijc[i*n+j]*jb[j*n+i];
324  free(jb);
325 
326  // check if -im*fc + (I-im*jb)*bx is inside bx.
327 
328  for(i=0; i< n;i++ )
329  {
330  bx[i]= bx[i]- c[i];
331  ev= bx[i];
332  for(j=0; j<n; j++ )
333  {
334  ev+= -ijc[i*n+j]*fc[j] - m[i*n+j] *bx[i];
335  }
336 // std::cout<<ev<<" --- "<<bx[i]<<std::endl;
337  if ( ev.m < bx[i].m ||
338  ev.M > bx[i].M )
339  {
340 // std::cout<<ev<<" not in "<<bx[i]<<std::endl;
341  return false;
342  }
343  }
344 // std::cout<<"found root in "<<bx<< "(ev="<<ev<<")"<<std::endl;
345  return ( true );
346  }
347 
348 
350  template<class POL>
351  bool exclude1(BOX*b, Seq<POL *>& S0)
352  {
353  Interval<double> ev;
354  Seq<Interval<double> > dom;
355  dom= b->template domain<double>();
356  DPOL tmp;
357 
358  for (unsigned i=0; i!=b->nbpol(); ++i)
359  {
360  let::assign(tmp, *S0[i] );
361  tensor::eval( ev , tmp.rep(),
362  dom , b->nbvar() );
363  if ( ev.m*ev.M > 0 )
364  {
365  // std::cout<<i<<" ev"<<
366  // dom<<"\nf= "<< *(S0[1])<<
367  // "\n f([])= " <<ev<<std::endl;
368  // if (td!=0)
369  // std::cout<<"!!!!!!----td: "<<td <<std::endl;
370  return true;
371  }
372 
373  }
374  return false;
375  };
376 
377 
379  TMPL
380  bool exclude2(BOX* b,DPOL * J)
381  {
382  Interval<double> ev;
383  Interval<double> * m;
384 
385  //Seq<POL> SS= b->system();
386  unsigned dim= b->nbvar();
387 
388  // Check Jacobian's sign
389  m= eval_poly_matrix( b->template domain<double>() ,J,dim);
390  ev= det(m,dim);
391  if ( ev.m*ev.M < 0 )
392  return false;
393 
394  int td= topological_degree_2d<POL, double>(b);
395 
396  return ( td==0 );
397  }
398 
399  TMPL
400  inline bool exclude3(BOX* b)
401  {
402  Seq<POL> S= b->system();
403  for (unsigned i=0; i!=b->nbpol(); ++i)
404  if ( no_variation( S[i]) )
405  return true;
406  return false;
407  }
408 
409 
410 //====================================================================
411 // ---------------------- Topological degree in 2d -------------------
412 //====================================================================
413 
415  template<class FT>
416  inline int sgn(FT a )
417  {
418  if (a==FT(0) ) return 0;
419  return ( (a>0) ? 1 : -1 );
420  }
421 
423  template<class POL, class FT>
424  int inline sgn(POL & f, FT a )
425  {
426  if (a==FT(-1) )
427  return sgn ( f[ f.rep().szs()[0]-1 ]);
428  else
429  return sgn ( f(a) );
430  };
431 
432  //template<class POL, class FT>
433  template<class POL, class FT>
435  {
436  /*-1=inf*/
437  typedef typename POL::scalar_t C;
438 
439  assert( b->nbvar() ==2 );
440  Seq<FT> p;
441  Seq<FT> tmp;
442  unsigned ev1(0), ev2(0), ev3(0), ev4(0);
443  FT p1[2],p2[2];
444  int tdeg;
445  unsigned i;
446 
447  POL fl0, fr0,fl1,fr1, s,
448  gl0, gr0,gl1,gr1 ;
449 
450  fl0=b->lface(0,1); gl0=b->lface(1,1);
451  fr0=b->rface(0,1); gr0=b->rface(1,1);
452  fl1=b->lface(0,0); gl1=b->lface(1,0);
453  fr1=b->rface(0,0); gr1=b->rface(1,0);
454 
455  s= fl0 * gl0 ;
456  p<< FT(0);p << FT(0) ;
457  tmp= solver<ring<C,MonomialTensor>, CFseparate>::template solve<FT>(s);
458  for (i=0;i< tmp.size(); ++i )
459  p<< tmp[i] << FT(0) ;
460 
461  s= fr1 * gr1;
462  p<< FT(-1);p << FT(0);
463  tmp= solver<ring<C,MonomialTensor>, CFseparate>::template solve<FT>(s);
464  for (i=0;i< tmp.size(); ++i )
465  p<< FT(-1) << tmp[i];
466 
467  s= fr0 * gr0 ;
468  p<< FT(-1);p << FT(-1) ;
469  tmp= solver<ring<C,MonomialTensor>, CFseparate>::template solve<FT>(s);
470  for (i=0;i< tmp.size(); ++i )
471  p<< tmp[i] << FT(-1) ;
472 
473  s= fl1 * gl1 ;
474  p<< FT(0);p << FT(-1) ;
475  tmp= solver<ring<C,MonomialTensor>, CFseparate>::template solve<FT>(s);
476  for (i=0;i< tmp.size(); ++i )
477  p<< FT(0) << tmp[i] ;
478 
479  p<< FT(0);p << FT(0) ;
480 
481  tdeg= 0;
482  for (i=0; i<p.size()-3; i+=2)
483  {
484  p1[0]= p[i] ;p1[1]=p[i+1];
485  p2[0]= p[i+2];p2[1]=p[i+3];
486 
487  if (p1[1]==FT(0) && p2[1]==FT(0)){
488  ev1= sgn( fl0, p1[0] );
489  ev3= sgn( fl0, p2[0] );
490  ev4= sgn( gl0, p1[0] );
491  ev2= sgn( gl0, p2[0] );
492  }else
493  if (p1[0]==FT(-1) && p2[0]==FT(-1)){
494  ev1= sgn( fr1, p1[1] );
495  ev3= sgn( fr1, p2[1] );
496  ev4= sgn( gr1, p1[1] );
497  ev2= sgn( gr1, p2[1] );
498  }else
499  if (p1[1]==FT(-1) && p2[1]==FT(-1)){
500  ev1= sgn( fr0, p1[0] );
501  ev3= sgn( fr0, p2[0] );
502  ev4= sgn( gr0, p1[0] );
503  ev2= sgn( gr0, p2[0] );
504  }else
505  if (p1[0]==FT(0) && p2[0]==FT(0)){
506  ev1= sgn( fl1, p1[1] );
507  ev3= sgn( fl1, p2[1] );
508  ev4= sgn( gl1, p1[1] );
509  ev2= sgn( gl1, p2[1] );
510  }
511  else
512  std::cout<< "TROUBLE!"<<std::endl;
513 
514  tdeg+= ( (ev1)*(ev2) - (ev3)*(ev4) );
515  }
516  return (tdeg/8);
517  }
518 
519 
520 } //namespace realroot
521 } //namespace mmx
522 
523 # undef DPOL
524 
int topological_degree_2d(BOX *b)
Definition: solver_mv_monomial_tests.hpp:434
const C & b
Definition: Interval_glue.hpp:25
TMPL Polynomial diff(const Polynomial &pol, int v)
Multivariate Polynomial Differentiation.
Definition: polynomial_fcts.hpp:99
void precondition(Seq< T > val, DPOL *mat, int n)
Definition: solver_mv_monomial_tests.hpp:70
R & rep(R &r)
Definition: shared_object.hpp:180
#define BOX
Definition: solver_mv_monomial_tests.hpp:26
Definition: fatarcs.hpp:23
TMPL bool exclude3(BOX *b)
Definition: solver_mv_monomial_tests.hpp:400
T * eval_poly_matrix(Seq< T > val, DPOL *mat, int n)
Definition: solver_mv_monomial_tests.hpp:91
TMPL DPOL * jacobian(Seq< POL * > &S0)
Definition: solver_mv_monomial_tests.hpp:49
TMPL bool miranda_test(Seq< POL > &S, const int i, const int j)
Definition: solver_mv_monomial_tests.hpp:194
bool exclude1(BOX *b, Seq< POL * > &S0)
Exclusion criteria (inteval arithmetic)
Definition: solver_mv_monomial_tests.hpp:351
void eval(Result &result, const bernstein< Coeff > &controls, const Parameters &parameters)
Definition: tensor_bernstein_fcts.hpp:195
size_type size() const
Definition: Seq.hpp:166
TMPL bool include2(BOX *b, DPOL *J)
Inclusion criteria (Jacobian+Topological Degree)
Definition: solver_mv_monomial_tests.hpp:274
Definition: solver.hpp:68
bool include3(BOX *b, DPOL *J, Seq< POL * > &S0)
Inclusion criteria based on Rump's test.
Definition: solver_mv_monomial_tests.hpp:299
TMPL void face(Polynomial &r, const Polynomial &p, int v, int f)
Definition: polynomial_fcts.hpp:188
int sgn(FT a)
Sign of a.
Definition: solver_mv_monomial_tests.hpp:416
#define TMPL
Definition: solver_mv_monomial_tests.hpp:24
TMPL POL
Definition: polynomial_dual.hpp:74
Definition: solver_ucf.hpp:27
T * submatrix(T *matrix, int order, int i, int j)
Definition: solver_mv_monomial_tests.hpp:119
T det(T *mat, int order)
Definition: solver_mv_monomial_tests.hpp:143
T m
Definition: Interval.hpp:52
const C & c
Definition: Interval_glue.hpp:45
double C
Definition: solver_mv_fatarcs.cpp:16
bool LUinverse(real_t *iM, real_t const *const M, unsigned n)
Definition: linear_doolittle.hpp:74
void assign(A &a, const B &b)
Generic definition of the assignement function.
Definition: assign.hpp:97
bool include1(BOX *b, DPOL *J)
Inclusion criteria (Miranda Test)
Definition: solver_mv_monomial_tests.hpp:210
bool has_sign_variation(Iterator b, Iterator e)
Definition: sign_variation.hpp:84
int signof_det(T *mat, const int &n)
Definition: solver_mv_monomial_tests.hpp:109
int signof(DPOL *p, Seq< FT > t)
Definition: solver_mv_monomial_tests.hpp:163
Definition: array.hpp:12
TMPL bool no_variation(POL &p)
True iff all coefficients of p have the same sign.
Definition: solver_mv_monomial_tests.hpp:40
#define DPOL
Definition: solver_mv_monomial_tests.hpp:25
TMPL bool exclude2(BOX *b, DPOL *J)
Exclusion criteria (topological degree)
Definition: solver_mv_monomial_tests.hpp:380
T M
Definition: Interval.hpp:52
#define assert(expr, msg)
Definition: shared_object.hpp:57
Home