Developer documentation

linear_householder.hpp
Go to the documentation of this file.
1 /********************************************************************
2  * This file is part of the source code of the realroot library.
3  * Author(s): J.P. Pavone, GALAAD, INRIA
4  * $Id: householder.hpp,v 1.1 2005/07/11 10:03:55 jppavone Exp $
5  ********************************************************************/
6 #ifndef realroot_SOLVE_SBDSLV_LINEAR_HOUSEHOLDER_HPP
7 #define realroot_SOLVE_SBDSLV_LINEAR_HOUSEHOLDER_HPP
8 //--------------------------------------------------------------------
9 #include <math.h>
11 //--------------------------------------------------------------------
12 namespace mmx {
13 //--------------------------------------------------------------------
14 namespace linear
15 {
16  /*
17  * M: matrice ring_sparseetrique a reduire, a la fin contient la matrice de transformation
18  * d: elements diagonaux
19  * e: au dessus de la diagonale (e[0] = 0 )
20  */
21  template< typename real_t >
22  void householder( real_t * M, real_t * d, real_t * e, int n )
23  {
24  int i,j,k,l;
25  real_t scale, hh, h, g, f;
26  real_t * mi = M + (n-1)*n;
27  for ( i = n-1; i >= 1; i--, mi -= n )
28  {
29  l = i-1;
30  h = scale = 0.0;
31  if ( l > 0 )
32  {
33  for ( k = 0; k <= l; scale += fabs(mi[k]), k ++ ) ;
34  if ( scale == 0.0 ) e[i] = mi[l];
35  else
36  {
37  for ( k = 0; k <= l; mi[k] /= scale, h += mi[k]*mi[k], k ++ ) ;
38  f = mi[l];
39  g = (f >= 0.0 ? -std::sqrt(h) : std::sqrt(h));
40  e[i] = scale*g;
41  h -= f*g;
42  mi[l] = f - g;
43  f = 0.0;
44  real_t * mj = M;
45  for ( j = 0; j <= l; j ++, mj += n ) {
46  mj[i] = mi[j]/h;
47  g = 0.0;
48  for ( k = 0; k <= j; g += mj[k]*mi[k], k ++ ) ;
49  for ( k = j+1; k<= l; g += M[k*n+j]*mi[k], k ++ ) ;
50  e[j] = g/h;
51  f += e[j]*mi[j];
52  };
53  hh = f /(h+h);
54  for ( j = 0; j <= l; j ++ )
55  {
56  f = mi[j];
57  e[j] = g = e[j] - hh*f;
58  for ( k = 0; k <= j; M[j*n+k] -= (f*e[k]+g*mi[k]), k ++ ) ;
59  };
60  }
61  }
62  else
63  e[i] = mi[l];
64  d[i] = h;
65  };
66 
67  d[0] = 0;
68  e[0] = 0;
69  mi = M;
70  for ( i = 0; i < n; i ++, mi += n )
71  {
72  l = i - 1;
73  if ( d[i] )
74  for ( j = 0; j <= l; j ++ )
75  {
76  g = 0.0;
77  for ( k = 0; k <= l; g += mi[k]*M[k*n+j], k ++ ) ;
78  for ( k = 0; k <= l; M[k*n+j] -= g*M[k*n+i], k ++ ) ;
79  };
80  d[i] = mi[i];
81  mi[i] = 1.0;
82  for ( j = 0; j <= l; j ++ ) M[j*n+i] = mi[j] = 0.0;
83  };
84  };
85 
86  template< typename real_t >
87  real_t pythag( const real_t& a, const real_t& b)
88  {
89  real_t fa = std::abs(a);
90  real_t fb = std::abs(b);
91  real_t c;
92  if ( fa > fb )
93  {
94  c = fb/fa;
95  return fa * std::sqrt(1.0+c*c);
96  }
97  else
98  {
99  c = fa/fb;
100  return fb * std::sqrt(1.0+c*c);
101  };
102  };
103 
104 
105  template< typename real_t >
106  void tqli( real_t * d, real_t * e, int n, real_t * z )
107  {
108  int m,l,iter,i,k;
109  real_t s,r,p,g,f,dd,c,b;
110  for ( i = 1; i < n; i ++ ) e[i-1] = e[i];
111  e[n-1] = 0.0;
112  for ( l = 0; l < n; l++ )//for ( l = 1; l <= n; l ++ )
113  {
114 
115  iter = 0;
116  do
117  {
118 
119  for ( m = l; m < n-1; m++ )// for ( m = 1; m <=n-1; m++ )
120  {
121  dd = std::abs(d[m])+std::abs(d[m+1]);
122  if ( (real_t)(std::abs(e[m])+dd) == dd )
123  { break; };
124  };
125  if ( m != l )
126  {
127  iter++;
128  assert(iter<30);
129  g = (d[l+1]-d[l])/(2.0*e[l]);
130  r = pythag(g,(real_t)1.0);
131  if ( g >= 0.0 ) g = d[m]-d[l]+e[l]/(g+std::abs(r));
132  else g = d[m]-d[l]+e[l]/(g-std::abs(r));
133  s = c = 1.0;
134  p = 0.0;
135  for ( i = m-1; i >= l; i-- )
136  {
137  f = s*e[i];
138  b = c*e[i];
139  e[i+1] = (r=pythag(f,g));
140  if ( r == 0.0 )
141  {
142  d[i+1] -= p;
143  e[m] = 0.0;
144  break;
145  };
146  s = f/r;
147  c = g/r;
148  g = d[i+1]-p;
149  r=(d[i]-g)*s+2.0*c*b;
150  d[i+1]= g +(p=s*r);
151  g = c*r-b;
152  for ( k = 0; k < n; k++ )// for ( k = 1; k <= n; k++ )
153  {
154  f = z[k*n+i+1];//f = z[k][i+1];
155  z[k*n+i+1] = s*z[k*n+i]+c*f;//z[k][i+1] = s*z[k][i]+c*f;
156  z[k*n+i] = c*z[k*n+i]-s*f;//z[k][i] = c*z[k][i]-s*f;
157  };
158  }
159  if ( r == 0.0 && i >= l ) continue;
160  d[l] -= p;
161  e[l] = g;
162  e[m] = 0.0;
163  };
164  }
165  while( m != l );
166  };
167  };
168 
169  template< class real_t >
170  void symeigen( real_t * M, real_t * d, int n )
171  {
172  real_t e[n];
173  householder( M, d, e, n );
174  tqli( d, e, n, M );
175  };
176 
177  template< typename real_t >
178  void cpolynom( real_t * p, real_t * M, int n )
179  {
180  real_t cp1[n+1];
181  real_t * p1 = cp1;
182  real_t * p0 = p;
183  int i,k,c;
184 
185  for ( k = 0; k <= n; p0[k] = p1[k] = 0, k ++ ) ;
186 
187  p0[0] = 1;
188  p1[0] = M[n*(n-1)+(n-1)];
189  p1[1] = -1;
190 
191  c = 0;
192 
193  for ( i = n-2; i >= 0; i -- )
194  {
195  real_t a = M[i*n+i];
196  real_t b = M[i*n+i+1];
197 
198  for ( k = 0; k <= n-2-i; k ++ ) p0[k] = -p0[k]*(b*b);
199  for ( k = 0; k <= n-1-i; k ++ ) p0[k] += a*p1[k];
200  for ( k = 1; k <= n-i; k ++ )
201  p0[k] -= p1[k-1];
202 // for ( k = 0; k <= n-1-i; k ++ )
203 // p0[k] += a*p1[k];
204 // for ( k = 1; k <= n-i; k ++ )
205 // p0[k] -= p1[k-1];
206  std::swap(p0,p1);
207  };
208 
209  if ( p1 != p )
210  std::copy( p1, p1 + n+1, p );
211  // if ( c ) std::copy( p1, p1 + n+1, p0 );
212  };
213 
214  template< typename real_t >
215  void caract_polynom( real_t * p, real_t * M, int n )
216  {
217  real_t d[n];
218  real_t e[n];
219  householder( M, d, e, n );
220  cpolynom( p, M, n );
221  };
222 
223  /*
224  struct slv1dprm : std::vector< real_t >
225  {
226  void output( const real_t& a, const real_t& b )
227  { push_back( (a+b)/2.0 ); };
228  };
229 
230  template< typename real_t >
231  void symeigen( real_t * vp, real_t * base, real_t * m,
232  int n, const real_t& eps = 1e-12 )
233  {
234  real_t tmp[n*n];
235  std::copy(m,m+n*n,tmp);
236  real_t p[n+1];
237  caract_polynom(p, m, n );
238  typedef solvers::descartes_solver< real_t, solvers::bsearch_newton<real_t> > solver_t;
239  solver_t tmp(n+1,eps);
240  slv1dprm svp;
241  tmp.solve( svp, p );
242  for ( unsigned i = 0; i < svp.size(); i ++ )
243 
244  };
245  */
246 };
247 //--------------------------------------------------------------------
248 } //namespace mmx
249 /********************************************************************/
250 #endif //
const C & b
Definition: Interval_glue.hpp:25
MP swap(const MP &P, int var_i, int var_j)
Definition: sparse_monomials.hpp:988
void caract_polynom(real_t *p, real_t *M, int n)
Definition: linear_householder.hpp:215
void scale(IntervalData< RT, Poly > &ID, const RT &a)
Definition: contfrac_intervaldata.hpp:221
void symeigen(real_t *M, real_t *d, int n)
Definition: linear_householder.hpp:170
TMPL void copy(Polynomial &r, const Polynomial &a)
Copy of a in r.
Definition: sparse_monomials.hpp:613
void tqli(real_t *d, real_t *e, int n, real_t *z)
Definition: linear_householder.hpp:106
void abs(Interval< C, r > &x, const Interval< C, r > &a)
Definition: Interval_fcts.hpp:185
scalar< T > sqrt(const scalar< T > &b)
Definition: scalar.hpp:501
real_t pythag(const real_t &a, const real_t &b)
Definition: linear_householder.hpp:87
const C & c
Definition: Interval_glue.hpp:45
void householder(real_t *M, real_t *d, real_t *e, int n)
Definition: linear_householder.hpp:22
Definition: array.hpp:12
void cpolynom(real_t *p, real_t *M, int n)
Definition: linear_householder.hpp:178
#define assert(expr, msg)
Definition: shared_object.hpp:57
Home